51Nod2903 稳定婚姻(Tarjan)

Problem

我们已知n对夫妻的婚姻状况,称第i对夫妻的男方为Bi,女方为Gi。若某男Bi与某女Gj曾经交往过(无论是大学,高中,亦或是幼儿园阶段,i≠j),则当某方与其配偶(即Bi与Gi或Bj与Gj)感情出现问题时,他们有私奔的可能性。不妨设Bi和其配偶Gi感情不和,于是Bi和Gj旧情复燃,进而Bj因被戴绿帽而感到不爽,联系上了他的初恋情人Gk……一串串的离婚事件像多米诺骨牌一般接踵而至。若在Bi和Gi离婚的前提下,这2n个人最终依然能够结合成n对情侣,那么我们称婚姻i为不安全的,否则婚姻i就是安全的。给定所需信息,你的任务是判断每对婚姻是否安全。

第一行为一个正整数n,表示夫妻的对数;

以下n行,每行包含两个字符串,表示这n对夫妻的姓名(先女后男),由一个空格隔开;

第n+2行包含一个正整数m,表示曾经相互喜欢过的情侣对数;

以下m行,每行包含两个字符串,表示这m对相互喜欢过的情侣姓名(先女后男),由一个空格隔开。

所有姓名字符串中只包含英文大小写字母,大小写敏感,长度不大于8,

保证每对关系只在输入文件中出现一次,输入文件的最后m行不会出现未在之前出现过的姓名,

这2n个人的姓名各不相同

输出文件共包含n行,第i行为“Safe”(如果婚姻i是安全的)或“Unsafe”(如果婚姻i是不安全的)。

Solution

二分图,夫妻女向男连边,旧情男向女连边,如果夫妻二人在同一个强连通分量内,那么找到夫妻男到女的一个环,关系在环上转移一下就离婚了,因此只需要求强连通分量即可。

Code

#include<stdio.h>
#include<iostream>
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
#include<string>
#include<stack>
#include<map>
#include<vector>
const int MAXN=10020;
const int MAXM=50020;
int n,m,idx,cnt;
int dfn[MAXN];
int low[MAXN];
bool instack[MAXN];
int g[MAXN];
struct E{
	int u,v,nex;
}e[MAXM];
stack<int>s;
vector<int>belong[MAXN];
void Tarjan(int u){
	dfn[u]=low[u]=++idx;
	s.push(u);
	instack[u]=true;
	for(int i=g[u];i>0;i=e[i].nex){
		int v=e[i].v;
		if(!dfn[v]){
			Tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(instack[v]){
			low[u]=min(low[u],dfn[v]);
		}
	}
	if(dfn[u]==low[u]){
		++cnt;
		int cur;
		do{
			cur=s.top();s.pop();
			instack[cur]=false;
			belong[cnt].push_back(cur);
		}while(cur!=u);
	}
}
map<string,int>mp;
int num;
int name[2*MAXN];
int main(){
	io_opt;
	cin>>n;
	string x,y;
	for(int i=1;i<=n;i++){
		cin>>x>>y;
		if(!mp[x]) mp[x]=++num;
		if(!mp[y]) mp[y]=++num;
		int xx=mp[x],yy=mp[y];
		name[2*i-1]=xx;
		name[2*i]=yy;
		e[i]=(E){xx,yy,g[xx]};g[xx]=i;
	}
	cin>>m;
	for(int i=n+1;i<=n+m;i++){
		cin>>x>>y;
		int xx=mp[x],yy=mp[y];
		e[i]=(E){yy,xx,g[yy]};g[yy]=i;
	}
	for(int i=1;i<=num;i++){
		if(!dfn[i]) Tarjan(i);
	}
	for(int i=1;i<=n;i++){
		if(low[name[2*i-1]]==low[name[2*i]]){
			cout<<"Unsafe"<<endl;
		}
		else{
			cout<<"Safe"<<endl;
		}
	}
	return 0;
}

原文地址:https://www.cnblogs.com/sz-wcc/p/12614481.html

时间: 2024-10-31 11:31:29

51Nod2903 稳定婚姻(Tarjan)的相关文章

luogu P1407 稳定婚姻-tarjan缩点

题目背景 原<工资>重题请做2397 题目描述 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关. 25岁的姗姗和男友谈恋爱半年就结婚,结婚不到两个月就离婚,是典型的“闪婚闪离”例子,而离婚的导火线是两个人争玩电脑游戏,丈夫一气之下,把电脑炸烂. 有社会工作者就表示,80后求助个案越来越多,有些是与父母过多干预有关.而根据民政部的统计,中国离婚五大城市首位是北京,其次是上海.深圳,广州和厦门,那么到底

【bzoj2140】: 稳定婚姻 图论-tarjan

[bzoj2140]: 稳定婚姻 哎..都是模板题.. 一眼看过去 哇 二分图哎 然后发现好像并不能匈牙利算法 自己xjb画两张图,发现二分图左向右连配偶的边,然后右向左连交往过的边 然后如果Bi Gi在同一个强连通分量里面就一定可以在Bi Gi离婚以后再增广一次 最开始用map维护一下名字就好了 1 /* http://www.cnblogs.com/karl07/ */ 2 #include <cstdlib> 3 #include <cstdio> 4 #include &l

BZOJ2140: 稳定婚姻

题解: 题意就是求二分图的必须边. 我们有结论: 在残量网络上跑tarjan,对于一条边(u,v) 如果该边满流||scc[u]==scc[v],那么该边是可行边. 因为如果scc[u]==scc[v],那么说明v到u有通路,我们把v-u的路以及u-v这条边全部反色,也就是匹配->非匹配,非匹配->匹配.同样还是最大匹配.这说明该边是可行的. 如果该边满流&&scc[u]!=scc[v],那么该边是必须边. 因为如果去掉这条边,最大匹配会减少1(想想看),所以该边必须出现在最大

uva 1175 Ladies&#39; Choice (稳定婚姻问题)

uva 1175 Ladies' Choice Background Teenagers from the local high school have asked you to help them with the organization of next year?s Prom. The idea is to find a suitable date for everyone in the class in a fair and civilized way. So, they have or

(算法)稳定婚姻匹配

题目: 婚介所登记了N位男孩和N位女孩,每个男孩都对N个女孩的喜欢程度做了排序,每个女孩都对N个男孩的喜欢程度做了排序,你作为月老,能否给出稳定的牵手方案? 稳定的定义:如果男孩i和女孩a牵手,但男孩i对女孩b更喜欢,而女孩b的男朋友j拼不过男孩i,则没有力量阻碍男孩i和女孩b的私奔,这即是不稳定的. 思路: 1962 年,美国数学家 David Gale 和 Lloyd Shapley 发明了一种寻找稳定婚姻的策略.不管男女各有多少人,不管他们各自的偏好如何,应用这种策略后总能得到一个稳定的婚

nyoj 月老的难题 (稳定婚姻问题)

百度了一下稳定婚姻问题.. 还有什么GS算法.. 以为什么高端的东西.. 尼玛结果代码跟上一题一模一样的好吗.. 醉了.. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 #include<queue> 7 #include<algorithm> 8 #include&l

UVALive 3989Ladies&#39; Choice(稳定婚姻问题)

题目链接 题意:n个男生和女生,先是n行n个数,表示每一个女生对男生的好感值排序,然后是n行n列式每一个男生的好感值排序,输出N行,即每个女生在最好情况下的男生的编号 分析:如果是求女生的最好情况下,就要从女生开始选,这样女生都是从最好的到不好的来选,而男生却相反--只能娶那些自己有可能最没好感的女生,因为男生是被动的,他最喜欢的女生不见的会向他求婚. 刘汝佳书上命名错了,so也跟着把男生当成女生了,懒得改命名了, 1 #include <iostream> 2 #include <cs

简单的稳定婚姻匹配

一.相关的定义 1.有一个男士集合和一个女士集合.每个男士都有一个优先级列表,把女士按潜在结婚对象进行优先级排序. 同样的,女士也有一个对潜在结婚对象的优先级列表. 婚姻匹配: 一个婚姻匹配M是一个包含n个(m,w)对的集合,每一对的成员都按照一对一的模式从两个不相交的n元素集合Y和X中选出.也就是说,Y中的每个男士m都只和X中的一位女士w配对,反正亦然.相当于一个二分图中,边来连接可能结婚的对象,两边的顶点代表X和Y,婚姻匹配也是图中的一个完美匹配. 婚姻的稳定:如果在匹配M中,,男士m和女士

poj 3478 The Stable Marriage Problem 稳定婚姻问题

题目给出n个男的和n个女的各自喜欢对方的程度,让你输出一个最佳搭配,使得他们所有人的婚姻都是稳定的. 所谓不稳婚姻是说,比如说有两对夫妇M1,F1和M2,F2,M1的老婆是F1,但他更爱F2;而F2的老公虽说是M2.但她更爱M1,这样的婚姻就是不稳婚姻,M1和F2理应结合,他们现在各自的婚姻都是错误的. 整个算法基于,男性轮流向女性求婚,每次求婚对象都是没有拒绝过自己且自己最喜欢的女性.而女性对于每个求婚者,若她是单身,则接受,否则,就看她更喜欢当前求婚者还是她的未婚夫,选择更好的那个. 这种执