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

Input
4 2
1 2
2 3
Output
1
2
2
1 3
Input
3 3
1 2
2 3
1 3
Output
-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(二分图判定-染色法)的更多相关文章

  1. CF687A. NP-Hard Problem[二分图判定]

    A. NP-Hard Problem time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  2. UVA - 10004 Bicoloring(判断二分图——交叉染色法 / 带权并查集)

    d.给定一个图,判断是不是二分图. s.可以交叉染色,就是二分图:否则,不是. 另外,此题中的图是强连通图,即任意两点可达,从而dfs方法从一个点出发就能遍历整个图了. 如果不能保证从一个点出发可以遍 ...

  3. 洛谷P1525 关押罪犯(并查集、二分图判定)

    本人蒟蒻,只能靠题解AC,看到大佬们的解题思路,%%%%%% https://www.luogu.org/problemnew/show/P1525 题目描述 S城现有两座监狱,一共关押着N名罪犯,编 ...

  4. [POJ2942]Knights of the Round Table(点双+二分图判定——染色法)

    建补图,是两个不仇恨的骑士连边,如果有环,则可以凑成一桌和谐的打麻将 不能直接缩点,因为直接缩点求的是连通分量,点双缩点只是把环缩起来 普通缩点                             ...

  5. hdu 2444(染色法判断二分图+最大匹配)

    The Accomodation of Students Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  6. Wrestling Match---hdu5971(2016CCPC大连 染色法判断是否是二分图)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5971 题意:有n个人,编号为1-n, 已知X个人是good,Y个人是bad,m场比赛,每场比赛都有一个 ...

  7. 染色法判断是否是二分图 hdu2444

    用染色法判断二分图是这样进行的,随便选择一个点, 1.把它染成黑色,然后将它相邻的点染成白色,然后入队列 2.出队列,与这个点相邻的点染成相反的颜色 根据二分图的特性,相同集合内的点颜色是相同的,即 ...

  8. 二分图判定+点染色/并查集 BestCoder Round #48 ($) 1002 wyh2000 and pupil

    题目传送门 /* 二分图判定+点染色:因为有很多联通块,要对所有点二分图匹配,若不能,存在点是无法分配的,no 每一次二分图匹配时,将点多的集合加大最后第一个集合去 注意:n <= 1,no,两 ...

  9. poj 2942 Knights of the Round Table(点双连通分量+二分图判定)

    题目链接:http://poj.org/problem?id=2942 题意:n个骑士要举行圆桌会议,但是有些骑士相互仇视,必须满足以下两个条件才能举行: (1)任何两个互相仇视的骑士不能相邻,每个骑 ...

  10. HDU2444(KB10-B 二分图判定+最大匹配)

    The Accomodation of Students Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

随机推荐

  1. linux拷贝命令,移动命令

    http://blog.sina.com.cn/s/blog_7479f7990101089d.html

  2. Android——eclipse下运行android项目报错 Conversion to Dalvik format failed with error 1解决

    在eclipse中导入android项目,项目正常没有任何错误,但是运行时候会报错,(clean什么的都没用了.....)如图: 百度大神大多说是jdk的问题,解决: 右键项目-Properties如 ...

  3. swift开发新项目总结

    新项目用swift3.0开发,现在基本一个月,来总结一下遇到的问题及解决方案   1,在确定新项目用swift后,第一个考虑的问题是用纯swift呢?还是用swift跟OC混编      考虑到新项目 ...

  4. linux上使用google身份验证器(简版)

    系统:centos6.6 下载google身份验证包google-authenticator-master(其实只是一个.zip文件,在windwos下解压,然后传进linux) #cd /data/ ...

  5. ReactNative入门(安卓)——API(上)

    Alert - 弹窗 通过 Alert.alert() 方法调用唤起原生弹窗,点击会触发 onPress 回调(参考下方代码)并清除弹窗. import React, { AppRegistry, C ...

  6. ABP框架 - 启动配置

    文档目录 本节内容: 配置ABP 替换内置服务 配置模块 为一个模块创建配置 ABP在启动时,提供基础框架和模型来配置和模块化. 置ABP 在预初始化事件中进行配置,示例: kid1412注:XmlL ...

  7. 随笔jade

    mixin在刚使用的时候写错,写成了minxin,然后进行命令生成,发现报错 查了蛮久,由于开发工具并没有提示错误,最后找到了这样的错误,记下来,望大家不要重复爬坑

  8. CSS样式表分类

    1.内联样式表 <p  style="font-size:11px;">内联样式表</p> 2.内嵌样式表 写在head标签里 <style  typ ...

  9. Spark 运行架构核心总结

    摘要: 1.基本术语 2.运行架构 2.1基本架构 2.2运行流程  2.3相关的UML类图  2.4调度模块: 2.4.1作业调度简介 2.4.2任务调度简介 3.运行模式 3.1 standalo ...

  10. Android笔记——Bundle类的作用

    Bundle类用作携带数据,它类似于Map,用于存放key-value键值对形式的值.相对于Map,它提供了各种常用类型的putXxx()/getXxx()方法,如:putString()/getSt ...