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 ( ...
随机推荐
- C# 数组的交集、差集、并集
C# 数组的交集.差集.并集 工作中经常会用这方面的知识来检查那些字段是必须输入的,那些是禁止输入. using System; using System.Collections.Generic; u ...
- Boost信号/槽signals2
信号槽是Qt框架中一个重要的部分,主要用来解耦一组互相协作的类,使用起来非常方便.项目中有同事引入了第三方的信号槽机制,其实Boost本身就有信号/槽,而且Boost的模块相对来说更稳定. signa ...
- UML图中经常用到几种的关系图例
学习这个东西挺奇怪的,时间一长就容易忘记,或者记不清楚.今天看到一些UML图的关系,发现有些出入了,索性就写下来,以后再忘记的时候过来看看. 在UML的类图中,常见的有以下几种关系: 继承(Gener ...
- Postman - 功能强大的 API 接口请求调试和管理工具
Postman 是一款功能强大的的 Chrome 应用,可以便捷的调试接口.前端开发人员在开发或者调试 Web 程序的时候是需要一些方法来跟踪网页请求的,用户可以使用一些网络的监视工具比如著名的 Fi ...
- 2-1 Linux 操作系统及常用命令
根据马哥linux初级视频 2-1.2-2来编辑 1. GUI与CLI GUI: Graphic User Interface CLI: Command Line Interface 注:在Windo ...
- Topshelf 学习 跨平台
Topshelf是一个开源的跨平台的宿主服务框架,支持Windows和Mono,只需要几行代码就可以构建一个很方便使用的服务宿主. 官网:http://topshelf-project.com Git ...
- 前端工程师手中的Sublime Text
原文地址:http://css-tricks.com/sublime-text-front-end-developers/ 我的Blog:http://cabbit.me/sublime-text-f ...
- 转职成为TypeScript程序员的参考手册
写在前面 作者并没有任何可以作为背书的履历来证明自己写作这份手册的分量. 其内容大都来自于TypeScript官方资料或者搜索引擎获得,期间掺杂少量作者的私见,并会标明. 大部分内容来自于http:/ ...
- WCF学习之旅—WCF中传统的异常处理(十六)
WCF中的异常处理 在软件开发过程中,不可能没有异常的出现,所以在开发过程中,对不可预知的异常进行解决时,异常处理显得尤为重要.对于一般的.NET系统来说,我们简单地借助try/catch可以很容易地 ...
- jQuery系列:Ajax
1. load(url, [data], [callback]) 1.1 解析 载入远程 HTML 文件代码并插入至 DOM 中. 语法格式: load(url, [data], [callback] ...