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

 1 #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 }
View Code

猜你喜欢

转载自www.cnblogs.com/violet-acmer/p/11785602.html
今日推荐