1129. Door Painting

http://acm.timus.ru/problem.aspx?space=1&num=1129

一条边会形成两个度 所以全图的度的和为偶数

所以度数为奇数的点有偶数个 假设有 n 个

然后将n个点进行处理 1,2配对 3,4配对

对应配对的两个点 如果已经有边 则删掉 如果没有则加上

这样的话每个点的度就是偶数了

然后从一个点出发 走遍所以可以到达的边 最后正好回到原点

对于每个点 进来和出去的次数正好相等 把进来标记为一种颜色 出去标记为另一种颜色

则每个点两种颜色的个数相等   当然要注意加的边 和减的边

每个点最多加了一条边 最多减了一条边 对某种颜色个数的影响是 1 符合题意

代码:

#include<iostream>

#include<cstdio>

#include<cstring>

#include<cmath>

#include<algorithm>

#include<vector>

#include<set>

#include<queue>

#include<stack>

#include<map>

#include<string>

#include<iomanip>

using namespace std;



#define LL long long

const int INF=0x3f3f3f3f;

const int N=105;

int road[N][N];

int color[N][N];

int n;

void dfs(int x)

{

    for(int l=1;l<=n;++l)

    {

        if(road[x][l]&&color[x][l]==0)

        {

            color[x][l]=1;

            color[l][x]=-1;

            dfs(l);

        }

    }

}

int main()

{

    //freopen("data.in","r",stdin);

    cin>>n;

    memset(road,0,sizeof(road));

    memset(color,0,sizeof(color));

    int m;

    vector<int>tmp;

    tmp.clear();

    for(int i=1;i<=n;++i)

    {

        cin>>m;

        if(m&1)

        tmp.push_back(i);

        while(m--)

        {

            int j;

            cin>>j;

            road[i][j]=1;

        }

    }

    for(unsigned int i=0;i<tmp.size();i+=2)

    {

        if(road[tmp[i]][tmp[i+1]]==0)

        {

            road[tmp[i]][tmp[i+1]]=2;

            road[tmp[i+1]][tmp[i]]=2;

        }else

        {

            color[tmp[i]][tmp[i+1]]=1;

            color[tmp[i+1]][tmp[i]]=-1;

        }

    }

    for(int i=1;i<=n;++i)

    {

        dfs(i);

    }

    for(int i=1;i<=n;++i)

    {

        for(int j=1;j<=n;++j)

        {

            if(road[i][j]==1)

            {

                if(color[i][j]==1)

                cout<<"Y ";

                else

                cout<<"G ";

            }

        }

        cout<<endl;

    }



    return 0;

}

 

 

 

 

你可能感兴趣的:(paint)