uva 11080

题意:放最少的士兵去监视所有的道路, 但士兵不可相邻

分析:由於不可相邻可以視同為不可同色(分成两种颜色), 对于一個连通图而言, 如果可以用两种颜色涂完,
那么较少使用的顏色则是放置士兵的个数。这题要小心有很多连通图 !

 

#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;
}

  

posted @ 2015-05-27 14:07  waterfull  阅读(467)  评论(0编辑  收藏  举报