P1330 封锁阳光大学
分析
分析题目的限制
相连两个点不能同时选要选最少的点将所有的边进行覆盖
提炼一下,我们能得到什么。
- 二分图,通过这两个条件,这个图一定是个二分图,不然一定无解。
- 我们选的点一定都是二分图中其中点数少的那一半。因为我们选择点互相之间不能有边。
因此,我们的思路就出来了,染色法判二分图,注意,图不一定是联通的,需要每一个连通图都是二分图。
对其中每一个二分图,我们答案加点数少的一半即可。
错点分析
其实,我看到之后,判断完二分图,我说,这不最小点覆盖问题嘛,直接跑一个匈牙利就行。
然后,我就不出意外的WA了。
原因也很简单,最小点覆盖问题,求的是选择最小的点,使得每一条边至少有一个顶点被选择,其中可能会选到,一条边的两个顶点。
这就跟题目产生很大的分歧了。
题目的要求只能选择互相之间无边的点。
AC_Code
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10,M = 2e5 + 10;
int h[N],e[M],ne[M],idx;
int color[N],match[N];
bool st[N];
int n,m,res,cnt1,cnt2;
void add(int a,int b)
{
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
bool dfs(int u,int c)
{
color[u]=c;
if(c==1) cnt1++;
else cnt2++;
for(int i=h[u];i!=-1;i=ne[i])
{
int j=e[i];
if(!color[j])
{
if(!dfs(j,3-c)) return false;
}else if(color[j]==c) return false;
}
return 1;
}
int main()
{
cin>>n>>m;
memset(h,-1,sizeof h);
while(m--)
{
int a,b;
cin>>a>>b;
add(a,b),add(b,a);
}
for(int i=1;i<=n;i++)
if(!color[i]){
cnt1=cnt2=0;
if(!dfs(i,1))
{
puts("Impossible");
return 0;
}
else res+=min(cnt1,cnt2);
}
cout<<res<<endl;
return 0;
}

浙公网安备 33010602011771号