poj 2585 拓扑排序
这题主要在于建图。对9个2*2的小块,第i块如果出现了不等于i的数字,那么一定是在i之后被brought的。可以从i到该数字建一条边。
图建好后,进行一次拓扑排序,判段是否存在环。若存在环,那么就是BROKEN,否则是CLEAN。
#include<iostream> #include<cstdio> #include<cstring> #define Maxn 102 #define Maxm 10010 using namespace std; int graphic[Maxn][Maxn],indegree[Maxn],n,m,map[Maxn][Maxn],vi[10]; int Topsort() { int i,j,k,num=0; for(i=1;i<=9;i++) { for(j=1;j<=9;j++) { if(indegree[j]==0) { indegree[j]--; for(k=1;k<=9;k++) if(graphic[j][k]) indegree[k]--; num++; break; } } } if(num<9) return 0; return 1; } int main() { char str[20]; int i,j; while(scanf("%s",&str),strlen(str)<9) { n=0; memset(vi,0,sizeof(vi)); memset(graphic,0,sizeof(graphic)); memset(indegree,0,sizeof(indegree)); for(i=1;i<=4;i++) { for(j=1;j<=4;j++) { scanf("%d",&map[i][j]); } } int k=0; for(i=1;i<=3;i++) for(j=1;j<=3;j++) { k++; if(map[i][j]!=k) { if(!graphic[k][map[i][j]]) { graphic[k][map[i][j]]=1; indegree[map[i][j]]++; } } if(map[i][j+1]!=k) { if(!graphic[k][map[i][j+1]]) { graphic[k][map[i][j+1]]=1; indegree[map[i][j+1]]++; } } if(map[i+1][j]!=k) { if(!graphic[k][map[i+1][j]]) { graphic[k][map[i+1][j]]=1; indegree[map[i+1][j]]++; } } if(map[i+1][j+1]!=k) { if(!graphic[k][map[i+1][j+1]]) { graphic[k][map[i+1][j+1]]=1; indegree[map[i+1][j+1]]++; } } } scanf("%s",&str); if(Topsort()) printf("THESE WINDOWS ARE CLEAN\n"); else printf("THESE WINDOWS ARE BROKEN\n"); } return 0; }