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 }

原文地址:https://www.cnblogs.com/violet-acmer/p/11785602.html

时间: 2024-11-06 11:40:07

HDU 5971"Wrestling Match"(二分图染色)的相关文章

HDU 5971 Wrestling Match (二分图)

题意:给定n个人的两两比赛,每个人要么是good 要么是bad,现在问你能不能唯一确定并且是合理的. 析:其实就是一个二分图染色,如果产生矛盾了就是不能,否则就是可以的. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #

hdu 5971 Wrestling Match 判断能否构成二分图

http://acm.hdu.edu.cn/showproblem.php?pid=5971 Wrestling Match Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 25    Accepted Submission(s): 15 Problem Description Nowadays, at least one wrestli

hdu 5971 Wrestling Match

Wrestling Match Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1031    Accepted Submission(s): 390 Problem Description Nowadays, at least one wrestling match is held every year in our country.

hdu 3081 hdu 3277 hdu 3416 Marriage Match II III IV //最大流的灵活运用

3081 题意: n个女孩选择没有与自己吵过架的男孩有连边(自己的朋友也算,并查集处理),2分图,有些边,求有几种完美匹配(每次匹配每个点都不重复匹配) 我是建二分图后,每次增广一单位,(一次完美匹配),再修改起点还有终点的边流量,继续增广,直到达不到完美匹配为止.网上很多是用二分做的,我觉得没必要...(网上传播跟风真严重...很多人都不是真正懂最大流算法的...) 3277 : 再附加一条件,每个女孩可以最多与k个自己不喜欢的男孩.求有几种完美匹配(同上). 我觉得:求出上题答案,直接ans

noip 2010 关押罪犯 (二分图染色 并茶几)

/* 二分图染色版本 两个监狱对应二部图的两部分 在给定的怨气值里二分 对于每一个Ci 进行染色判断是否合法 染色的时候 如果这条边的ci > Ci 这两个人就带分开 即染成不同的颜色 如果染色到某两个点颜色相同且怨气值>Ci 这个Ci就不合法 二分直到最后答案 */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 100

【hiho】hiho第三十周&#183;二分图染色判定

是时候认真学学二分图了... 光会模板没用的,打好基础最重要~ 题目: 字面意思,二分图染色判断,判断是否是二分图 思路: 要让该无向图成为一张二分图,必须得将点划为G1,G2两个集合 也就是,对于给定的任何一条边,其连接的两个节点不能同色 那么我们可以总结出一个方法: 对于当前结点: 1.若其未被染色,我们规定将其染成A色,记为1 2.遍历其所有相邻的染色点,有未染色的,染为B色,记为2,DFS之 注:一旦被染色,说明此点状态被唯一确定 那么我们可以得到判断条件: 1.染色过程是否发生冲突 附

UVA11080- Place the Guards(二分图染色)

题目链接 题意:放最少的士兵去监视所有的道路, 但士兵不可相邻,符合的话,就输出最少的士兵数,否则输出-1 思路:其实就是二分图染色,即黑白染色,然后选择黑白染色最少的那个颜色累加,但要注意可能有多个连通块,只要有一个连通块不符合的话,就不符合. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <algorithm> u

HDU 3605 Escape【二分图多重匹配】

题意: 有n个人去m个星球  告诉你每个人想去哪些星球和每个星球最多容纳多少人,问能不能让所有人都满足 分析: 二分图多重匹配 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 using namespace std; 6 7 const int maxn = 100005; 8 const int maxm = 15; 9 10

洛谷P1330 封锁阳光大学(二分图染色)

P1330 封锁阳光大学 题目描述 曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街.河蟹看到欢快的曹,感到不爽.河蟹决定封锁阳光大学,不让曹刷街. 阳光大学的校园是一张由N个点构成的无向图,N个点之间由M条道路连接.每只河蟹可以对一个点进行封锁,当某个点被封锁后,与这个点相连的道路就被封锁了,曹就无法在与这些道路上刷街了.非常悲剧的一点是,河蟹是一种不和谐的生物,当两只河蟹封锁了相邻的两个点时,他们会发生冲突. 询问:最少需要多少只河蟹,可以封锁所有道路并且不发生冲突. 输