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”。
现对每个牧场摆放一块标有大写字母”F”或者”J”的广告牌进行装饰。两个有道路相连的牧场,必须摆放不同字母的广告牌。
“F”字母广告牌的价格要高于”J”字母的广告牌,所以约翰想最大化地使用”J”字母广告牌,请输出这个最大的数目,如果没有可行的摆放方案,则输出”-1”。
Input
第一行为两个整数N和M。
接下来2..M行,每行两个整数,描述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”字母广告牌。
牧场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