[2016-03-07][UVALive][3212][Crime]

自闭症网瘾萝莉.ら 提交于 2020-01-26 06:19:26
[2016-03-07][UVALive][3212][Crime]

  • 时间:2016-03-06 13:51:13 星期日
  • 题目编号:[UVALive][3212][Crime]
  • 题目大意:端点交替着色黑白,求黑色的最少着色数
  • 输入:
    • 若干组数据
    • 每组数据
      •         n m 顶点数,边数
      •         接下去m行,边
  • 输出:黑色最少着色数,如果不能黑白间隔那么就输出Impossible
  • 分析:
    •         题目有若干个联通块,最后答案就是每个联通块最少着色数目之和,
    • 直接dfs对每个点交替着色,如果遇到已经着色的并且颜色一样,那么一定不能完成着色
    • 通过对两种着色的情况进行计数,最后得到最小着色数目,(而重新设置初始条件再跑一遍dfs比较两次的值)
  • 方法:dfs每个端点,每到一个端点没着色就着色,直到无法着色,如果遇到边两端颜色一样,就Impossible

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
typedef long long LL;
#define CLR(x,y) memset((x),(y),sizeof((x)))
#define FOR(x,y,z) for(int (x)=(y);(x)<(z);++(x))
#define FORD(x,y,z) for(int (x)=(y);(x)>=(z);--(x))
#define FOR2(x,y,z) for((x)=(y);(x)<(z);++(x))
#define FORD2(x,y,z) for((x)=(y);(x)>=(z);--(x))
int n,m;
const int maxn = 1000 + 10;
const int maxedge = maxn*maxn;
int head[maxn];
int nextt[maxedge];
int endd[maxedge];
void addedge(int from,int to){
        static int q = 2;
        endd[q] = to;
        nextt[q] = head[from];
        head[from] = q++;
}
void ini(){
        memset(head,-1,sizeof(head));
}
int vis[maxn],cnt[2];
int dfs(int u){
        ++cnt[vis[u]];
        for(int q = head[u];~q;q = nextt[q]){
                int v = endd[q];
                if(vis[v] == -1){
                        vis[v] = 1 - vis[u];
                        if(dfs(v))      return 1;
                }
                if(vis[u] == vis[v])    return 1;
        }
        return 0;
}
int main(){
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        while(~scanf("%d%d",&n,&m)){
                int u1,v1,fnlres = 0;ini();
                FOR(i,0,m){
                        scanf("%d%d",&u1,&v1);
                        addedge(u1,v1);
                        addedge(v1,u1);
                }
                CLR(vis,-1);
                FOR(i,1,n+1){
                        if(vis[i] == -1 && ~head[i]){
                                cnt[0] = cnt[1] = vis[i] = 0;
                                if(!dfs(i))     fnlres += min(cnt[0],cnt[1]);
                                else{
                                        fnlres = -1;
                                        break;
                                }
                        }
                }
                if(~fnlres)     printf("%d\n",fnlres);
                else puts("Impossible");
        }
        return 0;
}  








标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!