UVA-11080-Place the Guards (二分图染色)

我草..这题是二分图...开始没看出来....草..弱爆了...还有就是图不是连通的,可能有很多图

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

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

 

// File Name: 11080-1.cpp
// Author: Zlbing
// Created Time: 2013/4/10 15:45:15

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3f3f3f3f
#define LL long long
#define REP(i,r,n) for(int i=r;i<=n;i++)
#define RREP(i,n,r) for(int i=n;i>=r;i--)

const int MAXN=205;
vector<int>G[MAXN];
int color[MAXN];
int n,m;
bool dfs(int u,int& cnt,int& total)
{
    total++;
    if(color[u]==1)cnt++;
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i];
        if(color[v]==color[u])return false;
        if(!color[v]){
            color[v]=3-color[u];
            if(!dfs(v,cnt,total))return false;
        }
    }
    return true;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        REP(i,0,n)G[i].clear();
        REP(i,1,m)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            G[a].push_back(b);
            G[b].push_back(a);
        }
        CL(color,0);
        int ans=0;
        bool flag=true;
        REP(i,0,n-1)
        {
            if(color[i]==0)
            {
                color[i]=1;
                int cnt=0,total=0;
                if(!dfs(i,cnt,total)){
                    flag=false;
                    break;
                }
                if(total==1)ans++;
                else ans+=min(cnt,total-cnt);
            }
        }
        if(flag)printf("%d\n",ans);
        else printf("-1\n");
    }
    return 0;
}

 

posted @ 2013-04-10 16:09  z.arbitrary  阅读(1205)  评论(0编辑  收藏  举报