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;
}
原文地址:https://www.cnblogs.com/liulangye/p/2775134.html