URAL-1129. Door Painting(欧拉路和回路)

题意:

幼儿园里有很多房屋,房屋与房屋之间连以走廊,走廊与房屋之间有一扇门.幼儿园长想把门漆成绿色或者黄色,使得:任意一条走廊两头门的颜色不同;任意一间房屋上的门,绿色门的数量与黄色门的数量相差不超过1;

其实这题就是求多个欧拉路或回路..因为欧拉路的每个点的入度和出度相差不超过一.

分析:

将从房子出去的门染绿色,进去的门染红色..也就转换成出度和入度关系;

若每个房子有偶数个门,这整个图就是个欧拉回路,故一定能行

若有奇数个房子有奇数个门,则一定不行,...(不能构成欧拉路或欧拉回路)

则对于有偶数个房子有奇数个门,则将这偶数个门两两匹配,形成一条虚拟的走廊...则样就形成了欧拉回路了!!最后去掉加入的边即可

这题有重边,可能不联通有多条欧拉路

// File Name: 1129.cpp
// Author: Zlbing
// Created Time: 2013/5/3 13:38:34

#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=105;
int n;
int out[MAXN];
int G[MAXN][MAXN];
vector<int> odd;
vector<int> A[MAXN][MAXN];
int mat[MAXN][MAXN];
bool V[MAXN];
void dfs(int u){
    V[u]=true;
     for(int i=1;i<=n;i++)
     {
         while(G[u][i])
         {
             G[u][i]--;
             G[i][u]--;
             dfs(i);
             A[u][i].push_back(1);
             A[i][u].push_back(2);
         }
     }
}
int main()
{
    while(~scanf("%d",&n))
    {
        CL(out,0);
        CL(G,0);
        odd.clear();
        REP(i,1,n)
        {
            scanf("%d",&out[i]);
            if(out[i]%2)
                odd.push_back(i);
            REP(j,1,out[i])
            {
                int a;
                scanf("%d",&a);
                G[i][a]++;
            }
        }
        REP(i,1,n)
            REP(j,1,n)
            mat[i][j]=G[i][j];
        if(odd.size()%2)
        {
            printf("Impossible\n");
        }
        else{
            for(int i=0;i<odd.size();i+=2)
            {
                int u=odd[i];
                int v=odd[i+1];
                G[u][v]++;
                G[v][u]++;
            }
            CL(A,0);
            CL(V,false);
            for(int i=1;i<=n;i++)
                if(!V[i])
                    dfs(i);
            for(int i=1;i<=n;i++)
            {
                bool f=true;
                for(int j=1;j<=n;j++)
                {
                    int k=0;
                    while(mat[i][j])
                    {
                        mat[i][j]--;
                        if(!f)
                            printf(" ");
                        if(f)
                        {
                            f=false;
                        }
                        if(A[i][j][k]==1)
                            printf("G");
                        else printf("Y");
                        k++;
                    }
                }
                printf("\n");
            }
        }

    }
    return 0;
}

 

posted @ 2013-05-03 15:36  z.arbitrary  阅读(404)  评论(0编辑  收藏  举报