CodeForces - 688C:NP-Hard Problem (二分图&带权并查集)
Recently, Pari and Arya did some research about NP-Hard problems and they found the minimum vertex cover problem very interesting.
Suppose the graph G is given. Subset A of its vertices is called a vertex cover of this graph, if for each edge uv there is at least one endpoint of it in this set, i.e. or
(or both).
Pari and Arya have won a great undirected graph as an award in a team contest. Now they have to split it in two parts, but both of them want their parts of the graph to be a vertex cover.
They have agreed to give you their graph and you need to find two disjoint subsets of its vertices A and B, such that both A and B are vertex cover or claim it's impossible. Each vertex should be given to no more than one of the friends (or you can even keep it for yourself).
Input
The first line of the input contains two integers n and m (2 ≤ n ≤ 100 000, 1 ≤ m ≤ 100 000) — the number of vertices and the number of edges in the prize graph, respectively.
Each of the next m lines contains a pair of integers ui and vi (1 ≤ ui, vi ≤ n), denoting an undirected edge between ui and vi. It's guaranteed the graph won't contain any self-loops or multiple edges.
Output
If it's impossible to split the graph between Pari and Arya as they expect, print "-1" (without quotes).
If there are two disjoint sets of vertices, such that both sets are vertex cover, print their descriptions. Each description must contain two lines. The first line contains a single integer k denoting the number of vertices in that vertex cover, and the second line contains k integers — the indices of vertices. Note that because of m ≥ 1, vertex cover cannot be empty.
Examples
4 2
1 2
2 3
1
2
2
1 3
3 3
1 2
2 3
1 3
-1
题意:N点M边,能不能分为两个没有公共点的点集,二者都覆盖所有的边。
思路:因为每条边只有两个端点,所以两端点必须分到不同的集合,所以就说二分图判定,先判定完,然后dfs染色即可。
这里用到了带权的并查集优化了一下。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
int fa[maxn],vis[maxn],u[maxn],v[maxn],dis[maxn];
vector<int>G[maxn],a,b;
int find(int x){
if(x!=fa[x]){
int fx=find(fa[x]);
dis[x]^=dis[fa[x]];
//因为这里有压缩路径,所以是x到根距离与fax到根的距离差
fa[x]=fx;
}
return fa[x];
}
int Union(int x,int y){
int fx=find(x),fy=find(y);
if(fx==fy){
if(dis[x]==dis[y]) return false;
return true;
}
fa[fx]=fy; dis[fx]=dis[x]^dis[y]^;
return true;
}
void dfs(int x,int op){
vis[x]=;
if(op==) a.push_back(x); else b.push_back(x);
rep(i,,G[x].size()-) if(!vis[G[x][i]]) dfs(G[x][i],-op);
}
int main()
{
int N,M;
scanf("%d%d",&N,&M);
rep(i,,N) fa[i]=i;
rep(i,,M) {
scanf("%d%d",&u[i],&v[i]);
G[u[i]].push_back(v[i]);
G[v[i]].push_back(u[i]);
if(!Union(u[i],v[i])) return puts("-1"),;
}
rep(i,,N){ if(!vis[i]&&G[i].size()) dfs(i,);}
printf("%d\n",a.size());
rep(i,,a.size()-) printf("%d ",a[i]); puts("");
printf("%d\n",b.size());
rep(i,,b.size()-) printf("%d ",b[i]); puts("");
return ;
}
CodeForces - 688C:NP-Hard Problem (二分图&带权并查集)的更多相关文章
- CodeForces - 687D: Dividing Kingdom II (二分图&带权并查集)
Long time ago, there was a great kingdom and it was being ruled by The Great Arya and Pari The Great ...
- Codeforces Educational Codeforces Round 5 C. The Labyrinth 带权并查集
C. The Labyrinth 题目连接: http://www.codeforces.com/contest/616/problem/C Description You are given a r ...
- BZOJ4025 二分图 分治 并查集 二分图 带权并查集按秩合并
原文链接http://www.cnblogs.com/zhouzhendong/p/8683831.html 题目传送门 - BZOJ4025 题意 有$n$个点,有$m$条边.有$T$个时间段.其中 ...
- Codeforces Round #181 (Div. 2) B. Coach 带权并查集
B. Coach 题目连接: http://www.codeforces.com/contest/300/problem/A Description A programming coach has n ...
- 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 ...
- D. The Door Problem 带权并查集
http://codeforces.com/contest/776/problem/D 注意到每扇门都有两个东西和它连接着,那么,如果第i扇门的状态是1,也就是已经打开了,那么连接它的两个按钮的状态应 ...
- Codeforces 1499G - Graph Coloring(带权并查集+欧拉回路)
Codeforces 题面传送门 & 洛谷题面传送门 一道非常神仙的题 %%%%%%%%%%%% 首先看到这样的设问,做题数量多一点的同学不难想到这个题.事实上对于此题而言,题面中那个&quo ...
- codeforces 687D Dividing Kingdom II 带权并查集(dsu)
题意:给你m条边,每条边有一个权值,每次询问只保留编号l到r的边,让你把这个图分成两部分 一个方案的耗费是当前符合条件的边的最大权值(符合条件的边指两段点都在一个部分),问你如何分,可以让耗费最小 分 ...
- UVA - 10004 Bicoloring(判断二分图——交叉染色法 / 带权并查集)
d.给定一个图,判断是不是二分图. s.可以交叉染色,就是二分图:否则,不是. 另外,此题中的图是强连通图,即任意两点可达,从而dfs方法从一个点出发就能遍历整个图了. 如果不能保证从一个点出发可以遍 ...
随机推荐
- docker commit
不能将挂载的外部volume修改的内容一块commit
- iOS URL Loading System / HTTP 重定向 认识与学习
一个朋友问了我一个问题,需求是这样的:他要用本地的H5资源 替换 链接资源, 但是判断链接资源时候 因为一些操作请求本地化了之后 一些操作比如请求服务器使用的是http开头,然而本地资源一直是以f ...
- 3D立方体图片切换动画
在线演示 本地下载
- 容器rootfs
挂载在容器根目录上.用来为容器进程提供隔离后执行环境的文件系统,就是所谓的“容器镜像”: 它还有一个更为专业的名称:rootfs (根文件系统). 所以,一个最常见的rootfs,或者说容器镜像,会包 ...
- Go sync模块
// A WaitGroup waits for a collection of goroutines to finish.// The main goroutine calls Add to set ...
- sg函数的应用
刚刚接触到sg函数突然感觉到原来可以这么好用,sg函数应该算是博弈论中比较经典的东西了.下面来说说sg函数: 从网上搜集资料终于能看懂了下面解释来自http://www.cnblogs.com/cj6 ...
- asp.net web api history and how does it work?
https://blogs.msdn.microsoft.com/zxue/2012/11/07/what-is-asp-net-web-api-and-how-does-it-work/ https ...
- Codeforces Beta Round #27 (Codeforces format, Div. 2) E. Number With The Given Amount Of Divisors 反素数
E. Number With The Given Amount Of Divisors time limit per test 2 seconds memory limit per test 256 ...
- keystone DB in devstack
~$ mysql -u -p root mysql> use keystone; mysql> show tables;+------------------------+| Tables ...
- java的Random()类使用方法
//随机生成1~100之间的一个整数 int randomNumber = (int)(Math.random() * 100) + 1; System.out.println(randomNumbe ...