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; }