http://acm.hdu.edu.cn/showproblem.php?pid=3231
很巧妙地将问题转化为拓扑排序
View Code
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 5 const int N=2010; 6 bool g[3][N][N]; 7 int ind[3][N],n; 8 int topo[3][N]; 9 int x[N],y[N],z[N]; 10 bool toposort(int k) 11 { 12 memset(ind[k],0,sizeof(ind[k])); 13 for(int v=1;v<=n;v++) 14 for(int u=1;u<=n;u++) 15 if(g[k][u][v]) ind[k][v]++; 16 for(int i=0;i<n;i++) 17 { 18 int u; 19 for(u=1;u<=n;u++) 20 if(ind[k][u]==0) break; 21 if(u>n) return false; 22 topo[k][i]=u; ind[k][u]--; 23 for(int v=1;v<=n;v++) 24 if(g[k][u][v]) ind[k][v]--; 25 } 26 return true; 27 } 28 int main() 29 { 30 int m,C=0; 31 while(scanf("%d%d",&n,&m),n||m) 32 { 33 memset(g,0,sizeof(g)); 34 for(int i=0;i<3;i++) 35 for(int u=1;u<=n;u++) g[i][u][u+n]=1; 36 while(m--) 37 { 38 char op[2]; 39 int u,v; 40 scanf("%s%d%d",op,&u,&v); 41 if(op[0]=='I') 42 { 43 for(int i=0;i<3;i++) 44 g[i][v][u+n]=g[i][u][v+n]=1; 45 } 46 else 47 { 48 int k=op[0]-'X'; 49 g[k][u+n][v]=1; 50 } 51 } 52 n*=2; 53 bool flag=true; 54 for(int i=0;flag&&i<3;i++) 55 if(!toposort(i)) flag=false; 56 n/=2; 57 if(flag) 58 { 59 printf("Case %d: POSSIBLE\n",++C); 60 for(int i=0;i<2*n;i++) 61 x[topo[0][i]]=y[topo[1][i]]=z[topo[2][i]]=i; 62 for(int i=1;i<=n;i++) 63 printf("%d %d %d %d %d %d\n",x[i],y[i],z[i],x[i+n],y[i+n],z[i+n]); 64 } 65 else printf("Case %d: IMPOSSIBLE\n",++C); 66 printf("\n"); 67 } 68 return 0; 69 }