油漆门

有一些无向边,要求给每条边的两端点染成黄色和绿色且两端点染成的颜色不同,使得连向每一个房间绿端点的数量与黄端点的数量之差不超过1。没有重边。1<=n<=100。

做法1

我们可以把图中的所有环删掉,容易知道答案不变。

接下来图就变成了一个森林,对于一棵树,我们只要把孩向边间隔染色,第一条边染的颜色与父向边染的颜色不同,就可以满足条件。

做法2

我们把每两个奇度数的点之间连边,接下来图中就只剩下若干个环了,就可以直接暴搜了。

感觉第二种做法特别神啊!

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std;
int n,he[233][233],M=0;
int col[233][233];
typedef vector<int> vec;
vec vs[2333];
char yy[2333];
void dfs(int x)
{
    for(int i=1;i<=n;i++)
    {
        while(he[x][i])
        {
            --he[x][i]; --he[i][x];
            dfs(i); col[x][i]=1; col[i][x]=0;
        }
    } 
}
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
int main()
{
    FO(painting)
    yy[1]='G'; yy[0]='Y';
    scanf("%d",&n);
    int lst=0;
    for(int i=1;i<=n;i++)
    {
        int x,y; scanf("%d",&x);
        if(x&1)
        {
            if(!lst) lst=i;
            else he[i][lst]++, he[lst][i]++, lst=0;
        } 
        while(x--)
        {
            scanf("%d",&y);
            vs[i].push_back(y);
            he[i][y]++;
        }
    }
    for(int i=1;i<=n;i++) dfs(i);
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<vs[i].size();j++)
        {
            int c=vs[i][j];
            putchar(yy[col[i][c]]);
            putchar(' ');
        }
        putchar(10);
    }
}
posted @ 2016-06-18 17:15  fjzzq2002  阅读(277)  评论(0编辑  收藏  举报