10.20T4 二分图染色

Description

农民约翰有N(1<= N<=50,000)牧场,分别编号为1... N。牧场由M(1<= M<=100,000)条双向道路连接。道路i连接两个不同的牧场牧场A_i(1<= A_I<= N)和牧场B_i(1<= B_i<= N)。同一对牧场之间可能有多条道路连接。
现对每个牧场摆放一块标有大写字母”F”或者”J”的广告牌进行装饰。两个有道路相连的牧场,必须摆放不同字母的广告牌。
“F”字母广告牌的价格要高于”J”字母的广告牌,所以约翰想最大化地使用”J”字母广告牌,请输出这个最大的数目,如果没有可行的摆放方案,则输出”-1”。

Input

第一行为两个整数N和M。
接下来2..M行,每行两个整数,描述M条双向道路。

Output

输出共一行,一个整数,表示”J”字母广告牌的最大数目,无解则输出”-1”。

Sample Input

4 4 1 2 2 3 3 4 4 1

Sample Output

2

Hint

【样例1说明】
牧场1和3,或者牧场2和4使用”J”字母广告牌。


 
简单二分图染色,有可能有多个联通块
code:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #define N 1000005
 5 using namespace std;
 6 struct node {
 7     int u,v;
 8 } e[N];
 9 int first[N],nxt[N],cnt;
10 void add(int u,int v) {
11     e[++cnt].u=u;
12     e[cnt].v=v;
13     nxt[cnt]=first[u];
14     first[u]=cnt;
15 }
16 int num=0,co[N],num2=0;
17 void dfs(int x) {
18     for(int i=first[x]; i; i=nxt[i]) {
19         int v=e[i].v;
20         if(co[v]==1-co[x])continue;
21         else if(co[v]==-1) {
22             co[v]=1-co[x];
23             if(co[v]==1)num++;
24             else num2++;
25             dfs(v);
26         } 
27         else if(co[v]==co[x]){
28             cout<<-1;
29             exit(0);
30         }
31     }
32 }
33 int main() {
34     int n,m;
35     cin>>n>>m;
36     for(int i=1; i<=n; i++)co[i]=-1;
37     for(int i=1; i<=m; i++) {
38         int u,v;
39         cin>>u>>v;
40         add(u,v);
41         add(v,u);
42     }
43     int ans=0;
44     for(int i=1; i<=n; i++) {
45         if(co[i]==-1) {
46             num=0;
47             num2=1;
48             co[i]=0;
49             dfs(i);
50             ans+=max(num,num2);
51         }
52     }
53     //for(int i=1;i<=n;i++)cout<<co[i]<<" ";
54     cout<<ans;
55     return 0;
56 }

over

原文地址:https://www.cnblogs.com/saionjisekai/p/9822776.html