传送门: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;
}