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