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