版权声明:欢迎转载(标记出处),写得不好还请多指教 https://blog.csdn.net/quan_tum/article/details/83097639
刚看到这道题本来以为是稳定婚姻问题的
结果是这么一道题面不可描述的题目
每一对夫妻中女向男连边,而每一对情侣中男向女连边,这样才可以保证形成男->女->男->女 的环
求强连通分量,如果夫妻在同一个强连通分量里,那么是危险的,否则是不危险的
#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;
}