Decorating The Pastures[二分图染色判断]

Description
Farmer John has N (1 ≤ N ≤ 50,000) pastures, conveniently numbered 1…N, connected by M (1 ≤ M ≤ 100,000) bidirectional paths. Path i connects pasture Ai (1 ≤ Ai ≤ N) to pasture Bi (1 ≤ Bi ≤ N) with Ai ≠ Bi. It is possible for two paths to connect between the same pair of pastures.

Bessie has decided to decorate the pastures for FJ’s birthday. She wants to put a large sign in each pasture containing either the letter ‘F’ or ‘J’, but in order not to confuse FJ, she wants to be sure that two pastures are decorated by different letters if they are connected by a path.

The sign company insists on charging Bessie more money for an ‘F’ sign than a ‘J’ sign, so Bessie wants to maximize the number of ‘J’ signs that she uses. Please determine this number, or output -1 if there is no valid way to arrange the signs.

Input

  • Line 1: Two integers N and M.

  • Lines 2…M+1: Two integers, Ai and Bi indicating that there is a bidirectional path from Ai to Bi.

Output

  • Line 1: A single integer indicating the maximum number of ‘J’ signs that Bessie can use. If there is no valid solution for arranging the signs, output -1.

Sample Input

4 4
1 2
2 3
3 4
4 1

Sample Output

2

Hint
INPUT DETAILS:

The pastures and paths form the vertices and edges of a square.

OUTPUT DETAILS:

Bessie can either choose to label pastures 1 and 3 with ‘J’ signs, or alternatively pastures 2 and 4.

题意:
给你m条边,让你给这条边的两个顶点标记,一个标记“F”一个标记“J”,因为J比较便宜,要尽可能多”J“,如果不是二分图就输出”-1“。

解法
我们先染色判断是否为二分图。我们给一个顶点染1,一个染-1。进行dfs如果有颜色相同的点,则该图不是二分图,就输出-1。
如果是二分图我们就计算染色‘-1’和‘1’的数量,取它们大的数作为”J“的数量,需要注意的是,整个图不一定是连通的,我们每个顶点进行dfs染色时,必须重新计算‘-1’和‘1’的数,sum+上它们的较大者,最后输出sum。

AC代码:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
vector<int>a[50005];
int color[50005];
int book[50005]; 
int n,m;
int c1=0,c2=0;
int dfs(int u,int c)
{
	color[u]=c;
	if(c==1) c1++;
	else c2++;
	for(int i=0;i<a[u].size();i++){
		int v=a[u][i];
		if(color[v]==c)//同色 
		return 0;
		if(color[v]==0&&!dfs(v,-c))
		{
			return 0;
		}
	}
	return 1;
}
int main(void)
{
	int u,v;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&u,&v);
		a[u].push_back(v);
		a[v].push_back(u);//无向图  
	}
	int sum=0;c1=c2=0;
	//二分图染色 判断二分图 
	for(int i=1;i<=n;i++){
		if(color[i]==0)//还没染色 
		{
			if(!dfs(i,1))
			{
				printf("-1\n");
				return 0;
			}
			sum+=max(c1,c2);
			c1=0;c2=0;
		}
	}
	//合法
	/*c1=max(n-c1,c1);//图可能不连通 
	printf("%d\n",c1);*/
	printf("%d\n",sum);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值