图的染色【洛谷P1330】

传送门:https://www.luogu.org/problemnew/show/P1330

这是个图的染色问题。题目看起来很复杂,但是仔细分析可以发现,将相邻结点染成不同的颜色,这样就保证了相邻的点不同时选择。然后判断一下染色后的每一块,将较少的颜色的个数加起来就是答案。

重点是关注图怎么染色,怎么将相邻的点染成不同的颜色。

PS:本题还有并查集的做法,效率很高。我看懂了之后会更新一下并查集的做法。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
vector<int> G[maxn];
int sum[2];
int col[maxn];
int vis[maxn];
bool dfs(int now,int color)
{
	if(vis[now])
	{
		if(col[now]==color) return true;
		return false;
	}
	vis[now] = 1;
	sum[col[now]=color]++;
	bool found = true; 
	for(int i=0;i<G[now].size();i++)
	{
		found = found && dfs(G[now][i],1-color);
	}
	return found;
}
int main()
{
	int n,m;
	cin>>n>>m;
	int ans = 0;
	for(int i=0;i<m;i++)
	{
		int x,y;
		cin>>x>>y;
		G[x].push_back(y);
		G[y].push_back(x);
	}
	for(int i=1;i<=n;i++)
	{
		if(vis[i]) continue;
		sum[0] = sum[1] = 0;
		if(!dfs(i,0))
		{
			cout<<"Impossible"<<endl;
			return 0;
		}
		ans += min(sum[0],sum[1]);
	}
	cout<<ans<<endl;
	return 0;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值