[国家集训队]稳定婚姻
[Time Gate]
https://www.luogu.org/problemnew/show/P1407
【解题思路】
Tarjan求强连通分量,对于一对夫妻,如果两人在同一个强连通分量里,那么这对婚姻就是不安全的,反之,则是安全的
【code】
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<map> 6 using namespace std; 7 #define N 10005 8 #define M 300005 9 10 int n,m; 11 map<string,int>cou; // couple 12 13 struct node { 14 int v,nex; 15 }e[M]; 16 int tot,h[N]; 17 void add(int u,int v) { 18 e[++tot].v=v; 19 e[tot].nex=h[u]; 20 h[u]=tot; 21 } 22 23 inline int read() { 24 int tmp=0; 25 char ch=getchar(); 26 while(ch<'0'||ch>'9') ch=getchar(); 27 while(ch>='0'&&ch<='9') tmp=(tmp<<1)+(tmp<<3)+ch-'0',ch=getchar(); 28 return tmp; 29 } 30 31 bool ins[N]; 32 int s[N],top; 33 int cnt,belong[N]; 34 int dfn[N],low[N],idx; 35 void Tarjan(int u) { 36 dfn[u]=low[u]=++idx; 37 s[++top]=u; 38 ins[u]=1; 39 for(int i=h[u];i;i=e[i].nex) { 40 int v=e[i].v; 41 if(!dfn[v]) { 42 Tarjan(v); 43 low[u]=min(low[u],low[v]); 44 } 45 else if(ins[v]) low[u]=min(low[u],dfn[v]); 46 } 47 if(low[u]==dfn[u]) { 48 ++cnt; 49 do{ 50 belong[s[top]]=cnt; 51 ins[s[top]]=0; 52 }while(s[top--]!=u); 53 } 54 } 55 56 int main() 57 { 58 n=read(); 59 string gir,boy; 60 for(int i=1;i<=n;++i) { 61 cin>>gir>>boy; 62 cou[gir]=i; 63 cou[boy]=i+n; 64 add(i,i+n); 65 } 66 m=read(); 67 for(int i=1;i<=m;++i) { 68 cin>>gir>>boy; 69 add(cou[boy],cou[gir]); 70 } 71 for(int i=1;i<=n*2;++i) if(!dfn[i]) Tarjan(i); 72 for(int i=1;i<=n;++i) { 73 if(belong[i]==belong[i+n]) printf("Unsafe\n"); 74 else printf("Safe\n"); 75 } 76 return 0; 77 }