Box Relations HDU - 3231
考察:拓扑排序
不会写orz,蒟蒻本蒻了.完全不能从题目抽出模型来
这道题是x、y、z轴三个拓扑序列.
根据操作进行加边,要注意的是I操作要求的是x的最大坐标大于y的最小坐标.而x与y的关系并没有约束.画了一下图大概是因为y可以包括x
易错:
初始边注意不能根据操作加,如果有盒子不在操作里就会错误
1 #include <iostream> 2 #include <queue> 3 #include <cstring> 4 using namespace std; 5 const int N = 2010; 6 const int M = 100010; 7 int h[3][N],e[3][M],ne[3][M],d[3][N],idx[3],n,r,ans[3][N]; 8 void add(int a,int b,int w); 9 void inits() 10 { 11 memset(h,-1,sizeof(h)); memset(d,0,sizeof(d)); 12 memset(ans,0,sizeof(ans)); idx[0]=idx[1]=idx[2]=0; 13 for(int i=1;i<=n;i++) 14 { 15 for(int j=0;j<3;j++) { add(i,i+n,j); d[j][i+n]++; } 16 } 17 } 18 void add(int a,int b,int w) 19 { 20 e[w][idx[w]] = b,ne[w][idx[w]]=h[w][a],h[w][a]=idx[w]++; 21 } 22 bool topsort(int id)//每个维度都需要赋值 23 { 24 int cur = 0; 25 queue<int> q; 26 for(int i=1;i<=2*n;i++) if(!d[id][i]) q.push(i); 27 while(!q.empty()) 28 { 29 int x = q.front(); 30 q.pop(); 31 ans[id][x] = cur++; 32 for(int i=h[id][x];i!=-1;i=ne[id][i]) 33 { 34 int j = e[id][i]; 35 if(--d[id][j]==0) q.push(j); 36 } 37 } 38 if(cur==2*n) return true; 39 else return false; 40 } 41 void solve() 42 { 43 bool flag = 1; 44 for(int i=0;i<3&&flag;i++) 45 if(!topsort(i)) flag = false; 46 if(!flag) printf("IMPOSSIBLE\n"); 47 else{ 48 printf("POSSIBLE\n"); 49 for(int i=1;i<=n;i++) 50 printf("%d %d %d %d %d %d\n",ans[0][i],ans[1][i],ans[2][i],ans[0][i+n],ans[1][i+n],ans[2][i+n]); 51 } 52 } 53 int main() 54 { 55 // freopen("in.txt","r",stdin); 56 int kcase = 0; 57 while(scanf("%d%d",&n,&r)!=EOF&&n) 58 { 59 inits(); 60 printf("Case %d: ",++kcase); 61 for(int i=1;i<=r;i++) 62 { 63 char c; int x,y; 64 cin>>c; 65 scanf("%d%d",&x,&y); 66 if(c!='I') 67 { 68 // add(x,x+n,c-'X'); d[c-'X'][x+n]++; 69 // add(y,y+n,c-'X'); d[c-'X'][y+n]++; 70 add(x+n,y,c-'X'); d[c-'X'][y]++; 71 }else{ 72 for(int j=0;j<3;j++){ 73 // add(x,x+n,j); d[j][x+n]++; 74 // add(y,y+n,j); d[j][y+n]++; 75 add(y,x+n,j); d[j][x+n]++; 76 add(x,y+n,j); d[j][y+n]++; 77 // add(x,y,j); d[j][y]++; 78 } 79 } 80 } 81 solve(); 82 printf("\n"); 83 } 84 return 0; 85 }