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;
}
浙公网安备 33010602011771号