BZOJ2140稳定婚姻

版权声明:欢迎转载(标记出处),写得不好还请多指教 https://blog.csdn.net/quan_tum/article/details/83097639

传送门

刚看到这道题本来以为是稳定婚姻问题的

结果是这么一道题面不可描述的题目

每一对夫妻中女向男连边,而每一对情侣中男向女连边,这样才可以保证形成男->女->男->女 . . . ... 的环

t a r j a n tarjan 求强连通分量,如果夫妻在同一个强连通分量里,那么是危险的,否则是不危险的

#include<bits/stdc++.h>
#define il inline
using namespace std;
const int N=8005,M=40005;
string s1,s2;
map<string,int> d;
int n,m,k,tim,top,sum,h[N],dfn[N],low[N],v[N],s[N],c[N];
struct Edge{int to,nxt;}a[M];
il void add(int x,int y){a[++k].to=y,a[k].nxt=h[x],h[x]=k;}
il void tarjan(int x){
	dfn[x]=low[x]=++tim;v[x]=1;s[++top]=x;
	for(int i=h[x];i;i=a[i].nxt){
		int y=a[i].to;
		if(!dfn[y]){tarjan(y);if(low[y]<low[x]) low[x]=low[y];}
		else if(v[y]&&low[x]>dfn[y]) low[x]=dfn[y];
	}
	if(dfn[x]==low[x]){
		int i;++sum;
		do i=s[top--],v[i]=0,c[i]=sum;
		while(x!=i);
	}
}
int main(){
	ios::sync_with_stdio(0);
	cin>>n;
	for(int i=1;i<=n;++i) cin>>s1>>s2,d[s1]=i*2-1,d[s2]=i*2,add(i*2-1,i*2);
	cin>>m;
	for(int i=1;i<=m;++i) cin>>s1>>s2,add(d[s2],d[s1]);
	for(int i=1;i<=n;++i) if(!dfn[i*2-1]) tarjan(i*2-1);
	for(int i=1;i<=n;++i) puts(c[i*2]==c[i*2-1]?"Unsafe":"Safe");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/quan_tum/article/details/83097639