总体思路:裸裸的二分染色题
, 每一记录联通块的总节点数和染色相同的节点数 , 每一次用有较小数目那种颜色的节点去更新答案
注意: 可能存在只有一个节点的联通块
//
// main.cpp
// UVa11080
//
// Created by Fuxey on 15/10/5.
// Copyright © 2015年 corn.crimsonresearch. All rights reserved.
//
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <list>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 230;
int n , m , c[maxn];
vector<int> g[maxn];
int color_now , color_all;
bool dfs(int u)
{
color_all++;
if(c[u]==1) color_now++;
for(int i=0;i<g[u].size();i++)
{
int v = g[u][i];
if(c[v]==c[u]) return false;
if(c[v]==3-c[u]) continue;
c[v] = 3-c[u];
if(!dfs(v)) return false;
}
return true;
}
int main(int argc, const char * argv[]) {
int t;
cin>>t;
while(t-- && cin>>n>>m)
{
for(int i=0;i<n;i++) g[i].clear();
while(m--)
{
int a , b;
cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
memset(c, 0, sizeof(c));
int res = 0;
for(int i=0;i<n;i++) if(!c[i])
{
color_all = color_now = 0;
c[i] = 1;
if(!dfs(i)) { res = -1; break; }
res += max(min(color_now, color_all-color_now),1);
}
cout<<res<<endl;
}
return 0;
}