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

【bzoj2140】: 稳定婚姻

哎。。都是模板题。。

一眼看过去 哇 二分图哎

然后发现好像并不能匈牙利算法

自己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  
View Code

 

posted @ 2017-04-21 21:43  karl07  阅读(173)  评论(0编辑  收藏  举报