哎。。都是模板题。。
一眼看过去 哇 二分图哎
然后发现好像并不能匈牙利算法
自己xjb画两张图,发现二分图左向右连配偶的边,然后右向左连交往过的边
然后如果Bi Gi在同一个强连通分量里面就一定可以在Bi Gi离婚以后再增广一次
最开始用map维护一下名字就好了
1 /* http://www.cnblogs.com/karl07/ */ 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <algorithm> 7 #include <stack> 8 #include <map> 9 #include <string> 10 using namespace std; 11 12 const int N=100005; 13 struct edge{ 14 int next,to; 15 }e[N*4]; 16 int n,m,ade,cnt,cq; 17 int first[N],low[N],dfn[N],vis[N],ins[N],pos[N]; 18 stack <int> S; 19 map <string,int> mp; 20 21 void addedge(int x,int y){ 22 e[++ade].to=y; 23 e[ade].next=first[x]; 24 first[x]=ade; 25 } 26 27 #define s e[x].to 28 void dfs(int p){ 29 dfn[p]=low[p]=++cnt; 30 ins[p]=vis[p]=1; 31 S.push(p); 32 for (int x=first[p];x;x=e[x].next){ 33 if (!vis[s]){ 34 dfs(s); 35 if (ins[s]) low[p]=min(low[p],low[s]); 36 }else{ 37 if (ins[s]) low[p]=min(low[p],dfn[s]); 38 } 39 } 40 if (low[p]==dfn[p]){ 41 cq++; 42 while (S.top()!=p){ 43 pos[S.top()]=cq; 44 ins[S.top()]=0; 45 S.pop(); 46 } 47 pos[S.top()]=cq; 48 ins[S.top()]=0; 49 S.pop(); 50 } 51 } 52 53 int main(){ 54 scanf("%d",&n); 55 for (int i=1;i<=n;i++){ 56 char a[20],b[20]; 57 scanf("%s%s",a,b); 58 mp[a]=i,mp[b]=i+n; 59 addedge(i,i+n); 60 } 61 scanf("%d",&m); 62 for (int i=1;i<=m;i++){ 63 char a[20],b[20]; 64 scanf("%s%s",a,b); 65 addedge(mp[b],mp[a]); 66 } 67 for (int i=1;i<=n*2;i++) if (!vis[i]) dfs(i); 68 for (int i=1;i<=n;i++){ 69 if (pos[i]==pos[i+n]) puts("Unsafe"); else puts("Safe"); 70 } 71 return 0; 72 } 73