用到二分图的的一个定理:就是二分图一定能用两种颜色来着色。。。然后搜一下就行
AC代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef struct{
int to;
int next;
}Edge;
typedef struct{
int n, tag;
}Node;
Edge edge[500020];
int head[300010];
int tot, N;
int mark[200010];
bool have[20020];
void add_edge( int a, int b ){
edge[tot].to = b;
edge[tot].next = head[a];
head[a] = tot++;
edge[tot].to = a;
edge[tot].next = head[b];
head[b] = tot++;
}
int BFS( int start ){
int sum = 0;
int n0 = 0;
int now = 0;
Node ss;
ss.n = start;
ss.tag = 0;
mark[start] = 0;
queue<Node> q;
q.push( ss );
sum++;
n0++;
while( !q.empty() ){
Node n = q.front();
q.pop();
for( int i = head[n.n]; i != -1; i = edge[i].next ){
int to = edge[i].to;
Node temp;
temp.n = to;
temp.tag = n.tag ^ 1;
if( mark[to] != -1 ){
continue;
}
mark[to] = temp.tag;
sum++;
if( temp.tag == 0 ){
n0++;
}
q.push( temp );
}
}
return max( n0, sum - n0 );
}
int main(){
int T, Case = 1, M;
cin >> T;
while( T-- ){
cin >> M;
N = 0;
tot = 0;
memset( mark, -1, sizeof( mark ) );
memset( head, -1, sizeof( head ) );
memset( have, false, sizeof( have ) );
for( int i = 0; i < M; i++ ){
int temp1, temp2;
cin >> temp1 >> temp2;
N = max( temp1, N );
N = max( temp2, N );
have[temp1] = true;
have[temp2] = true;
add_edge( temp1, temp2 );
add_edge( temp2, temp1 );
}
int ans = 0;
for( int i = 1; i <= N; i++ ){
if( mark[i] != -1 || !have[i] ) continue;
ans += BFS( i );
}
cout << "Case " << Case++ << ": " << ans << endl;
}
return 0;
}