二分图判定+点染色/并查集 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$元环的图,试判断其是否为一个可平面图(如果存在一种画法,使得该图与给出的图同构且边除了在顶点处以外互相不相交,则称其 ...
随机推荐
- POJ3669 Meteor Shower
http://poj.org/problem?id=3669 类似于迷宫的一道题 但是并没有 给出迷宫具体什么样 但是题目已说在坐标轴的第一象限 然后障碍就是 流星雨所砸范围 安全位置:永远不会发生危 ...
- msp430入门学习06
msp430的IO端口的第一功能 msp430入门学习
- UVA 10564_ Paths through the Hourglass
题意: 由0-9的数字组成一个形如沙漏的图形,要求从第一行开始沿左下或者右下到达最后一行,问有多少种不同的路径,使最后路径上的整数之和为给定的某个数. 分析: 简单计数dp,从最后一行开始,设dp[i ...
- java读取大文本文件
原文:http://blog.csdn.net/k21325/article/details/53886160 小文件当然可以直接读取所有,然后放到内存中,但是当文件很大的时候,这个方法就行不通了,内 ...
- 在线文档分享工具 ShowDoc
原文:https://www.oschina.net/p/showdoc https://www.showdoc.cc/
- commons-lang常用工具类StringEscapeUtils
原文:https://my.oschina.net/mousai/blog/88832 在apache commons-lang(2.3以上版本)中为我们提供了一个方便做转义的工具类,主要是为了防止s ...
- 条款十五: 让operator=返回*this的引用
c++程序员经常犯的一个错误是让operator=返回void,这好象没什么不合理的,但它妨碍了连续(链式)赋值操作,所以不要这样做. 一般情况下几乎总要遵循operator=输入和返回的都是类对象的 ...
- [Typescript Kaop-ts] Use AOP in Vue Components with TypeScript and Kaop-ts
Aspect Oriented Programming, AOP, allows to reuse logic across an entire app in a very neat way, dec ...
- 新IOS编程语言 Swift 新编译器Xcode6
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_ ...
- WindowFromPoint -- 获得包括指定点的窗体的句柄
WindowFromPoint 函数功能: 该函数获得包括指定点的窗体的句柄. 函数原型: HWND WindowFromPoint(POINT Point): 參数: Point:指定一个被检 ...