HDU 5971"Wrestling Match"(二分图染色)
•题意
给出 n 个人,m 场比赛;
这 m 场比赛,每一场比赛中的对决的两人,一个属于 "good player" 另一个属于 "bad player";
给出你 x 个已经确定的"good player" 和 y 个已经确定的 "bad player"。
问是否可以将这 n 个人划分成两类,其中一类属于 "good player",另一类属于 "bad player";
即不存在某人即属于 "good player" 又属于 "bad player";
如果能,输出 "YES",反之,输出 "NO";
•题解
对于每一场比赛的两人 $u,v$,连一条双向边 $u\rightarrow v\ ,\ v\rightarrow u$;
然后 DFS 染色。
先从已经确定的 $x+y$ 个人开始,染色与其相关的人,矛盾就输出 "NO";
然后对于不确定的人,枚举染色, 矛盾就输出 "NO";
如果不存在矛盾,输出 "YES";
•Code
View Code1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e3+50; 4 const int M=1e4+50; 5 6 int n,m,x,y; 7 int num; 8 int head[N]; 9 struct Edge 10 { 11 int to; 12 int next; 13 }G[M<<1]; 14 void addEdge(int u,int v) 15 { 16 G[num]={v,head[u]}; 17 head[u]=num++; 18 } 19 int col[N];///0:Good , 1:bad 20 int g[N]; 21 int b[N]; 22 bool ok; 23 24 void DFS(int u,int flag) 25 { 26 col[u]=flag; 27 for(int i=head[u];~i && !ok;i=G[i].next) 28 { 29 int v=G[i].to; 30 31 if(col[v] == -1) 32 DFS(v,flag^1); 33 34 if(col[v] == col[u])///u,v对立,如果出现col[u]=col[v],矛盾 35 ok=true; 36 } 37 } 38 char *Solve() 39 { 40 for(int i=1;i <= x;++i) 41 { 42 int u=g[i]; 43 ok=false; 44 if(col[u] == -1) 45 DFS(u,0); 46 if(ok || col[u] == 1) 47 return "NO"; 48 } 49 for(int i=1;i <= y;++i) 50 { 51 int u=b[i]; 52 if(col[u] == -1) 53 DFS(u,1); 54 55 if(ok || col[u] == 0) 56 return "NO"; 57 } 58 for(int i=1;i <= n;++i) 59 { 60 ok=false; 61 if(col[i] == -1 && head[i] != -1) 62 DFS(i,0); 63 64 if(ok) 65 return "NO"; 66 } 67 return "YES"; 68 } 69 void Init() 70 { 71 num=0; 72 for(int i=0;i <= n;++i) 73 { 74 col[i]=-1; 75 head[i]=-1; 76 } 77 } 78 int main() 79 { 80 // freopen("C:\\Users\\hyacinthLJP\\Desktop\\C++WorkSpace\\in&&out\\contest","r",stdin); 81 while(~scanf("%d%d%d%d",&n,&m,&x,&y)) 82 { 83 Init(); 84 for(int i=1;i <= m;++i) 85 { 86 int u,v; 87 scanf("%d%d",&u,&v); 88 addEdge(u,v); 89 addEdge(v,u); 90 } 91 for(int i=1;i <= x;++i) 92 scanf("%d",g+i); 93 for(int i=1;i <= y;++i) 94 scanf("%d",b+i); 95 puts(Solve()); 96 } 97 return 0; 98 }