题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25835
思路:对每一个连通块将其染色,然后取颜色相同的最多的点,最后全部加起来即可。
PS:一开始没考虑到有可能有些点不出现,WA了好多次,然后改成将出现的点标记即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define MAXN 222222 struct Edge{
int v,next;
}edge[MAXN<<]; int n,m,NE;
int head[MAXN]; void Insert(int u,int v)
{
edge[NE].v=v;
edge[NE].next=head[u];
head[u]=NE++;
} int color[MAXN],block;
vector<vector<int> >g; void dfs(int u,int state)
{
color[u]=state;
g[block].push_back(u);
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(color[v]==)dfs(v,-state);
}
} int main()
{
int _case,u,v,t=;
scanf("%d",&_case);
while(_case--){
scanf("%d",&m);
n=;
NE=;
memset(head,-,sizeof(head));
memset(color,-,sizeof(color));
while(m--){
scanf("%d%d",&u,&v);
Insert(u,v);
Insert(v,u);
color[u]=color[v]=;
n=max(n,max(u,v));
}
block=;
g.clear();
g.resize(n+);
for(int i=;i<=n;i++){
if(color[i]==){
dfs(i,);
block++;
}
}
int ans=,ans1=,ans2=;
for(int i=;i<block;i++){
ans1=ans2=;
for(int j=;j<g[i].size();j++){
if(color[g[i][j]]==)ans1++;
else if(color[g[i][j]]==)ans2++;
}
ans+=max(ans1,ans2);
}
printf("Case %d: %d\n",t++,ans);
}
}