题意:放最少的士兵去监视所有的道路, 但士兵不可相邻
分析:由於不可相邻可以視同為不可同色(分成两种颜色), 对于一個连通图而言, 如果可以用两种颜色涂完,
那么较少使用的顏色则是放置士兵的个数。这题要小心有很多连通图 !
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<queue>
#include<vector>
#include<stack>
#include<set>
using namespace std;
vector<int> e[205];
int n,m,vis[205],stk[205],k;
bool dfs(int u)
{
stk[++k]=u;
for(int i=0;i<e[u].size();i++)
{
int v=e[u][i];
if(vis[v]==0)
{
vis[v]=3-vis[u];
if(!dfs(v))
return false;
}
else
{
if(vis[v]==vis[u])
return false;
}
}
return true;
}
int main()
{
int tt;
scanf("%d",&tt);
while(tt--)
{
int ans=0;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
e[i].clear();
memset(vis,0,sizeof(vis));
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
e[x].push_back(y);
e[y].push_back(x);
}
bool flag=true;
for(int i=0;i<n;i++)
{
if(vis[i]==0)
{
k=0;
int cnt=0;
vis[i]=1;
if(!dfs(i))
{
flag=false;
break;
}
for(int i=1;i<=k;i++)
{
if(vis[stk[i]]==1)
cnt++;
}
cnt=min(cnt,k-cnt);
if(k==1)
cnt=1;
ans+=cnt;
}
}
if(!flag)
printf("-1\n");
else
printf("%d\n",ans);
}
return 0;
}