二分图判定+点染色/并查集 BestCoder Round #48 ($) 1002 wyh2000 and pupil
/*
二分图判定+点染色:因为有很多联通块,要对所有点二分图匹配,若不能,存在点是无法分配的,no
每一次二分图匹配时,将点多的集合加大最后第一个集合去
注意:n <= 1,no,两个集合都至少有一人;ans == n,扔一个给另一个集合
*/
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <map>
using namespace std; const int MAXN = 1e5 + ;
const int INF = 0x3f3f3f3f;
vector<int> G[MAXN];
int col[MAXN];
int cnt[];
int n, m; bool DFS(int u)
{
for (int i=; i<G[u].size (); ++i)
{
int v = G[u][i];
if (col[v] == -) {
col[v] = - col[u]; cnt[col[v]]++;
if (!DFS (v)) return false;
}
else if (col[v] == col[u]) return false;
} return true;
} void work(void)
{
memset (col, -, sizeof (col));
int ans = ;
for (int i=; i<=n; ++i)
{
if (col[i] == -)
{
col[i] = ; cnt[] = ; cnt[] = ;
if (!DFS (i)) {
puts ("Poor wyh"); return ;
}
ans += max (cnt[], cnt[]);
}
}
if (ans == n) ans--;
printf ("%d %d\n", ans, n - ans);
} int main(void) //BestCoder Round #48 ($) 1002 wyh2000 and pupil
{
int t; scanf ("%d", &t);
while (t--)
{
scanf ("%d%d", &n, &m);
if (n <= ) {
puts ("Poor wyh"); continue;
}
for (int i=; i<=n; ++i) G[i].clear ();
for (int i=; i<=m; ++i)
{
int u, v; scanf ("%d%d", &u, &v);
G[u].push_back (v); G[v].push_back (u);
}
work ();
} return ;
}
/*
并查集:有点像POJ食物链的做法, 分为(1, n)和(n+1, 2*n)两个集合,两种情况都试一下。
rt[i] == -1表示是该集合的根,用sz数组记录集合的大小
*/
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <map>
using namespace std; const int MAXN = 1e5 + ;
const int INF = 0x3f3f3f3f;
int n, m;
struct UF {
int rt[MAXN*], sz[MAXN*], sz2[MAXN*];
void init(void) {
memset (rt, -, sizeof (rt));
for (int i=; i<=*n; ++i) sz[i] = (i <= n), sz2[i] = (i > n);
}
int Find(int x) {
return rt[x] == - ? x : rt[x] = Find (rt[x]);
}
void Union(int x, int y) {
x = Find (x); y = Find (y);
if (x == y) return ;
rt[x] = y;
sz[y] += sz[x]; sz2[y] += sz2[x];
}
bool same(int x, int y) {
return Find (x) == Find (y);
}
}uf; int main(void) //BestCoder Round #48 ($) 1002 wyh2000 and pupil
{
int t; scanf ("%d", &t);
while (t--)
{
scanf ("%d%d", &n, &m);
bool ok = true; uf.init ();
for (int i=; i<=m; ++i)
{
int u, v; scanf ("%d%d", &u, &v);
if (!ok) continue;
if (uf.same (u, v) || uf.same (u+n, v+n)) ok = false;
else uf.Union (u, v+n), uf.Union (u+n, v);
} if (!ok || n <= ) puts ("Poor wyh");
else if (m == ) printf ("%d 1\n", n - );
else {
int ans = ;
for (int i=; i<=n; ++i) {
if (uf.rt[i] == -) {
ans += min (uf.sz[i], uf.sz2[i]);
}
}
printf ("%d %d\n", n - ans, ans);
}
} return ;
}
并查集做法
二分图判定+点染色/并查集 BestCoder Round #48 ($) 1002 wyh2000 and pupil的更多相关文章
- 暴力+降复杂度 BestCoder Round #39 1002 Mutiple
题目传送门 /* 设一个b[]来保存每一个a[]的质因数的id,从后往前每一次更新质因数的id, 若没有,默认加0,nlogn复杂度: 我用暴力竟然水过去了:) */ #include <cst ...
- 矩阵快速幂---BestCoder Round#8 1002
当要求递推数列的第n项且n很大时,怎么快速求得第n项呢?可以用矩阵快速幂来加速计算.我们可以用矩阵来表示数列递推公式比如fibonacci数列 可以表示为 [f(n) f(n-1)] = [f(n ...
- 贪心/二分查找 BestCoder Round #43 1002 pog loves szh II
题目传送门 /* 贪心/二分查找:首先对ai%=p,然后sort,这样的话就有序能使用二分查找.贪心的思想是每次找到一个aj使得和为p-1(如果有的话) 当然有可能两个数和超过p,那么an的值最优,每 ...
- Manacher BestCoder Round #49 ($) 1002 Three Palindromes
题目传送门 /* Manacher:该算法能求最长回文串,思路时依据回文半径p数组找到第一个和第三个会文串,然后暴力枚举判断是否存在中间的回文串 另外,在原字符串没啥用时可以直接覆盖,省去一个数组空间 ...
- noip 2010 关押罪犯 二分答案+二分图染色 || 并查集
题目链接 题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值&q ...
- BZOJ1997 HNOI2010 平面图判定 planar (并查集判二分图)
题意 判断一个存在哈密顿回路的图是否是平面图. n≤200,m≤10000n\le200,m\le10000n≤200,m≤10000 题解 如果一定存在一个环,那么连的边要么在环里面要么在外面.那么 ...
- hdu 1829 &poj 2492 A Bug's Life(推断二分图、带权并查集)
A Bug's Life Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- bzoj4025二分图(线段树分治 并查集)
/* 思维难度几乎没有, 就是线段树分治check二分图 判断是否为二分图可以通过维护lct看看是否链接出奇环 然后发现不用lct, 并查集维护奇偶性即可 但是复杂度明明一样哈 */ #include ...
- Luogu3209 HNOI2010 平面图判定 平面图、并查集
传送门 题意:$T$组数据,每组数据给出一个$N$个点,$M$条边,并存在一个$N$元环的图,试判断其是否为一个可平面图(如果存在一种画法,使得该图与给出的图同构且边除了在顶点处以外互相不相交,则称其 ...
随机推荐
- 【NOIP2017练习】鏖战字符串(斜率优化DP)
题意: 在决胜局中,Abwad决定和nbc鏖战字符串,比的是谁能更快地将一个“量子态的字符串”删除.“量子态的字符串”的每个字符都有一个删除难度dif[i].“量子态的字符串”非常顽固,只能先分割成若 ...
- 【HDOJ6148】Valley Numer(数位DP)
题意: 1≤T≤200 ● 1≤length(N)≤100 思路: 设f[i,j,k,l]为第i位为j,前i位是否贴上限(0/1),递减或递增(0/1)方案数 g[i,j,k]为不到n位,第i位为j, ...
- set(集合)数据类型【七】
一.概述:(类似于Java的Set,不允许有重复元素) 在Redis中,我们可以将Set类型看作为没有排序的字符集合,和List类型一样,我们也可以在该类型的数据值上执行添加.删除或判断某一元素是否存 ...
- [bzoj2251][2010BeiJing Wc]外星联络_后缀数组
外星联络 bzoj-2251 2010-BeiJing Wc 题目大意:题目链接. 注释:略. 想法: 这咋做啊????一看数据范围才$3\cdot 10^3$. 建立后缀数组. 所以我们将所有后缀排 ...
- select语句中会影响查询效率的因素
1.没有创建索引,或者没有正确使用索引;2.存在死锁的情况,从而导致select语句挂起; 3.返回不必要的列,如很多人喜欢在程序中使用select * from 这样会查询表或视图中的所有字段,如果 ...
- Windows 10 S中的Device Guard详解(上篇)
本文探讨Windows 10 S(下称Win10S)中的Device Guard(设备保护,下称DG).我将提取策略,并弄清楚在默认Win10S系统上可以和不可以运行什么.我将在下一篇文章中介绍在不安 ...
- C#使用全局钩子(hook),SetWindowsHookEx返回0、不回调的解决
http://www.csharpwin.com/csharpspace/3766r5747.shtml 在.net 2005平台下 在使用全局hook时,总是遇见SetWindowsHookEx的返 ...
- kafka-manager 的编译和使用(附安装包)
kafka-manager 的编译和使用(附安装包) 学习了:https://my.oschina.net/wangjiankui/blog/653139
- Lvs 负载均衡 (VS/NAT模式)
一.LVS简介 LVS是 Linux Virtual Server 的简称,也就是Linux虚拟服务器.这是一个由章文嵩博士发起的一个开源项目,它的官方网站是 http://www.linuxvirt ...
- 李洪强iOS开发之动态获取UILabel的bounds
李洪强iOS开发之动态获取UILabel的bounds 在使用UILabel存放字符串时,经常需要获取label的长宽数据,本文列出了部分常用的计算方法. 1.获取宽度,获取字符串不折行单行显示时所需 ...