hdu1824 Let's go home(2-sat)

Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2776    Accepted Submission(s): 1204


Problem Description
小时候,乡愁是一枚小小的邮票,我在这头,母亲在那头。
                        —— 余光中

集训是辛苦的,道路是坎坷的,休息还是必须的。经过一段时间的训练,lcy决定让大家回家放松一下,但是训练还是得照常进行,lcy想出了如下回家规定,每一个队(三人一队)或者队长留下或者其余两名队员同时留下;每一对队员,如果队员A留下,则队员B必须回家休息下,或者B留下,A回家。由于今年集训队人数突破往年同期最高记录,管理难度相当大,lcy也不知道自己的决定是否可行,所以这个难题就交给你了,呵呵,好处嘛~,免费**漂流一日。
 
Input
第一行有两个整数,T和M,1<=T<=1000表示队伍数,1<=M<=5000表示对数。
接下来有T行,每行三个整数,表示一个队的队员编号,第一个队员就是该队队长。
然后有M行,每行两个整数,表示一对队员的编号。
每个队员只属于一个队。队员编号从0开始。
 
Output
可行输出yes,否则输出no,以EOF为结束。
 
Sample Input
1 2
0 1 2
0 1
1 2
 
2 4
0 1 2
3 4 5
0 3
0 4
1 3
1 4
Sample Output
yes
no

思路:

拆点,给每个点一个hash值,队长单独一个,两个队员共用一个,相当于他们之间连通

假设队长为A,队员为B,初始连接A->B',B'->A,A'->B,B->A'

之后输入的两个点连接A->B',B->A'

最后判断队长和队员是不是同一个连通分量中的,是为yes,否则no

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N=4e3+5,M=5e3+5;
 5 int low[N],dfn[N],Stack[N],belong[N];
 6 bool inStack[N];
 7 int n,m,tot,tag,top;
 8 vector<int> G[N];
 9 map<int,int> mp;
10 
11 void init(){
12     top=tag=0;
13     memset(low,0,sizeof low);
14     memset(dfn,0,sizeof dfn);
15     memset(Stack,0,sizeof Stack);
16     memset(belong,0,sizeof belong);
17     memset(inStack,false,sizeof inStack);
18     for(int i=0;i<N;i++){
19         G[i].clear();
20     }
21     mp.clear();
22 }
23 
24 void tarjan(int u){
25     int v;
26     low[u]=dfn[u]=++tot;
27     Stack[++top]=u;
28     inStack[u]=true;
29     for(int i=0;i<G[u].size();i++){
30         v=G[u][i];
31         if(dfn[v]==0){
32             tarjan(v);
33             low[u]=min(low[u],low[v]);
34         }
35         else if(inStack[v]==true){
36             low[u]=min(low[u],dfn[v]);
37         }
38     }
39     if(dfn[u]==low[u]){
40         tag++;
41         do{
42             v=Stack[top--];
43             inStack[v]=false;
44             belong[v]=tag;
45         }while(u!=v);
46     }
47 }
48 
49 int main(){
50     int x,y,z;
51     while(~scanf("%d%d",&n,&m)){
52         init();
53         for(int i=0,k=0;i<n;i++){
54             scanf("%d%d%d",&x,&y,&z);
55             mp[x]=k++,mp[y]=k,mp[z]=k++;
56             G[mp[x]*2].push_back(mp[y]*2+1);
57             G[mp[y]*2+1].push_back(mp[x]*2);
58             G[mp[y]*2].push_back(mp[x]*2+1);
59             G[mp[x]*2+1].push_back(mp[y]*2);
60         }
61         for(int i=0;i<m;i++){
62             scanf("%d%d",&x,&y);
63             G[mp[x]*2].push_back(mp[y]*2+1);
64 //            G[mp[y]*2+1].push_back(mp[x]*2);
65             G[mp[y]*2].push_back(mp[x]*2+1);
66 //            G[mp[x]*2+1].push_back(mp[y]*2);
67         }
68         for(int i=0;i<4*n;i++){
69             if(dfn[i]==0){
70                 tot=0;
71                 tarjan(i);
72             }
73         }
74         int flag=1;
75         for(int i=0;i<4*n;i+=4){
76             if(belong[i]==belong[i+2]){
77                 flag=0;
78                 break;
79             }
80         }
81         if(flag==1)printf("yes\n");
82         else printf("no\n");
83     }
84 }

猜你喜欢

转载自www.cnblogs.com/ChangeG1824/p/11695149.html