C - NP-Hard Problem(二分图判定-染色法)
Crawling in process... Crawling failed Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u
Description
Input
Output
Sample Input
Sample Output
Hint
Description
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.
Sample Input
- 4 2
1 2
2 3
- 1
2
2
1 3
- 3 3
1 2
2 3
1 3
- -1
Sample Output
Hint
In the first sample, you can give the vertex number 2 to Arya and vertices numbered 1 and 3 to Pari and keep vertex number 4 for yourself (or give it someone, if you wish).
In the second sample, there is no way to satisfy both Pari and Arya.
题意:给你m组边的俩端点,若能构成二分图输出左右俩点集和个数,若不能输出-1.(若能构成二分图则给出的边的俩端点分别在左右俩个集团,不能出现一条边的俩点在一边)
思路:染色,给俩边的点染不同的颜色
代码:
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <vector>
- const int MAX=1e5+5;
- using namespace std;
- vector <int>mp[MAX];
- int d[MAX];
- int vis[MAX];
- int n,m;
- int dfs(int x,int f)
- {
- vis[x]=1;
- d[x]=f;
- int flag;
- for(int i=0;i<mp[x].size();i++)
- {
- if(d[mp[x][i]]==d[x])
- return flag=0;
- if(d[mp[x][i]]==0)
- {
- d[mp[x][i]]=-1*f;
- if(!dfs(mp[x][i],-1*f))
- return flag=0;
- }
- }
- return flag=1;
- }
- int main()
- {
- while(cin>>n>>m)
- {
- int a,b,flag=1;
- for(int i=0;i<MAX;i++)
- mp[i].clear();
- for(int i=0;i<m;i++)
- {
- scanf("%d%d",&a,&b);
- mp[a].push_back(b);
- mp[b].push_back(a);
- }
- memset(d,0,sizeof(d));
- memset(vis,0,sizeof(vis));
- for(int i=1;i<=n;i++)
- {
- if(!vis[i])
- {
- if(!dfs(i,1))
- {flag=0;break;}
- }
- }
- if(!flag)
- cout<<-1<<endl;
- else
- {
- int q=0,p=0;
- for(int i=1;i<=n;i++)
- {
- if(d[i]==1)
- q++;
- if(d[i]==-1)
- p++;
- }
- cout<<q<<endl;
- for(int i=1;i<=n;i++)
- if(d[i]==1)
- printf("%d ",i);
- cout<<endl;
- cout<<p<<endl;
- for(int i=1;i<=n;i++)
- if(d[i]==-1)
- printf("%d ",i);
- cout<<endl;
- }
- }
- }
代码改良:
- #include <iostream>
- #include <vector>
- #include <cstring>
- #include <cstdio>
- const int MAX=1e5+5;
- using namespace std;
- vector<int>mp[MAX],ans1,ans2;
- int d[MAX],n,m;
- int dfs(int x)
- {
- if(d[x]==0)
- d[x]=1;
- if(d[x]==1)
- ans1.push_back(x);
- if(d[x]==-1)
- ans2.push_back(x);
- for(int i=0;i<mp[x].size();i++)
- {
- if(d[x]==d[mp[x][i]])
- return 0;
- if(d[mp[x][i]]==0)
- {d[mp[x][i]]=-1*d[x];
- if(!dfs(mp[x][i]))
- return 0;}
- }
- return 1;
- }
- int main()
- { int a,b;
- while(cin>>n>>m)
- { for(int i=1;i<=n;i++)
- mp[i].clear();
- ans1.clear();
- ans2.clear();
- for(int i=0;i<m;i++)
- {
- scanf("%d%d",&a,&b);
- mp[a].push_back(b);
- mp[b].push_back(a);
- }
- int flag=1;
- memset(d,0,sizeof(d));
- for(int i=1;i<=n;i++)
- {
- if(d[i]==0)
- {
- if(!dfs(i))
- {
- flag=0;
- break;
- }
- }
- }
- if(!flag)
- cout<<-1<<endl;
- else
- {
- cout<<ans1.size()<<endl;
- for(int i=0;i<ans1.size();i++)
- printf("%d ",ans1[i]);
- cout<<endl;
- cout<<ans2.size()<<endl;
- for(int i=0;i<ans2.size();i++)
- printf("%d ",ans2[i]);
- cout<<endl;
- }
- }
- }
C - NP-Hard Problem(二分图判定-染色法)的更多相关文章
- CF687A. NP-Hard Problem[二分图判定]
A. NP-Hard Problem time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- UVA - 10004 Bicoloring(判断二分图——交叉染色法 / 带权并查集)
d.给定一个图,判断是不是二分图. s.可以交叉染色,就是二分图:否则,不是. 另外,此题中的图是强连通图,即任意两点可达,从而dfs方法从一个点出发就能遍历整个图了. 如果不能保证从一个点出发可以遍 ...
- 洛谷P1525 关押罪犯(并查集、二分图判定)
本人蒟蒻,只能靠题解AC,看到大佬们的解题思路,%%%%%% https://www.luogu.org/problemnew/show/P1525 题目描述 S城现有两座监狱,一共关押着N名罪犯,编 ...
- [POJ2942]Knights of the Round Table(点双+二分图判定——染色法)
建补图,是两个不仇恨的骑士连边,如果有环,则可以凑成一桌和谐的打麻将 不能直接缩点,因为直接缩点求的是连通分量,点双缩点只是把环缩起来 普通缩点 ...
- hdu 2444(染色法判断二分图+最大匹配)
The Accomodation of Students Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K ( ...
- Wrestling Match---hdu5971(2016CCPC大连 染色法判断是否是二分图)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5971 题意:有n个人,编号为1-n, 已知X个人是good,Y个人是bad,m场比赛,每场比赛都有一个 ...
- 染色法判断是否是二分图 hdu2444
用染色法判断二分图是这样进行的,随便选择一个点, 1.把它染成黑色,然后将它相邻的点染成白色,然后入队列 2.出队列,与这个点相邻的点染成相反的颜色 根据二分图的特性,相同集合内的点颜色是相同的,即 ...
- 二分图判定+点染色/并查集 BestCoder Round #48 ($) 1002 wyh2000 and pupil
题目传送门 /* 二分图判定+点染色:因为有很多联通块,要对所有点二分图匹配,若不能,存在点是无法分配的,no 每一次二分图匹配时,将点多的集合加大最后第一个集合去 注意:n <= 1,no,两 ...
- poj 2942 Knights of the Round Table(点双连通分量+二分图判定)
题目链接:http://poj.org/problem?id=2942 题意:n个骑士要举行圆桌会议,但是有些骑士相互仇视,必须满足以下两个条件才能举行: (1)任何两个互相仇视的骑士不能相邻,每个骑 ...
- HDU2444(KB10-B 二分图判定+最大匹配)
The Accomodation of Students Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K ( ...
随机推荐
- css3更改input单选和多选的样式
在项目开发中我们经常会遇到需要更改input单选和多选样式的情况,今天就给大家介绍一种简单改变input单选和多选样式的办法. 在这之前先简单介绍一下:before伪类 :before 选择器向选定的 ...
- JavaScript学习笔记(二)——闭包、IIFE、apply、函数与对象
一.闭包(Closure) 1.1.闭包相关的问题 请在页面中放10个div,每个div中放入字母a-j,当点击每一个div时显示索引号,如第1个div显示0,第10个显示9:方法:找到所有的div, ...
- 分享两个BPM配置小技巧
1.小技巧 流程图修改后发布的话版本号会+1,修改次数多了之后可能会导致版本号很高,这个时候可以将流程导出,然后删除对应的流程包再导入,发布数据模型和流程图之后,版本清零 2.小技巧 有的同事入职后使 ...
- Android之使用文件进行IPC
一.文件进行IPC介绍 共享文件也是一种不错的进程间通信方式,两个进程通过读/写同一个文件来交换数据.在Windows上,一个文件如果被加了排斥锁将会导致其他线程无法对其进行访问,包括读写,而由于An ...
- docker4dotnet #4 使用Azure云存储构建高速 Docker registry
使用Docker来构建应用程序最常见的操作就是 docker run 或者 docker pull了,但是由于众所周知的原因,在国内想要高速稳定的获取docker hub上面的资源并不是件容易的事情, ...
- 设置WindowServer2012 时间同步NTP
在powershell中以管理员身份运行以下命令即可 w32tm /config /manualpeerlist:pool.ntp.org /syncfromflags:MANUAL Stop-Ser ...
- [Unity3D]利用Raycast实现物体的选择与操作
本文系作者原创 转载请注明出处 如果是一个2D的平面项目或者说需要在三维空间选择一个物体时(经常表现为抓取物件),我们需要用到Raycast事件 那么首先先说说什么是Raycast 按照字面上来理解的 ...
- Mono 4.0 Mac上运行asp.net mvc 5.2.3
Mono 4.0 已经发布,二进制包已经准备好,具体的发布说明参见:http://www.mono-project.com/docs/about-mono/releases/4.0.0/. 今天在Ma ...
- 一步步开发自己的博客 .NET版(9、从model first替换成code first 问题记录)
为什么要改用code first 用过code first的基本上都不会再想用回model first或是db first(谁用谁知道).不要问我为什么不一开始就直接使用code first,因为那个 ...
- 一种简单的md5加盐加密的方法(防止彩虹表撞库)
md5加密(或者说摘要算法)大家都很熟悉了 就不解释了 现在很多数据库设计都喜欢用单向加密的方式保存密码,验证时对提交的密码再次加密之后做密文对比 /// <summary> 使用MD5加 ...