标签:拓扑排序
链接:http://poj.org/problem?id=2585
题意:有一个4*4的屏幕,有9个窗口各占2*2大小,保证不会存在一个窗口完全覆盖任一个窗口,但每个窗口都会部分被其他窗口覆盖(因为4*4和2*2 = =、)现在需要你判断电脑是否死机。(死机的话会出现无法判断A覆盖B还是B覆盖A的情况)
思路:无法判断A覆盖B还是B覆盖A,可以当做是图中A和B之间存在环,我们可以把每个窗口当做一个顶点,如果A覆盖了B,就以A为起点、B为终点连一条有向边,这样建完图之后入度为0的点就是没有没覆盖的窗口,然后进行拓扑排序,相当于每次关闭掉一个没有被覆盖的窗口,如果最后所有窗口都能被关闭,说明没有死机,否则(即存在环)说明死机。
#include<cstring> #include<string> #include<fstream> #include<iostream> #include<iomanip> #include<cstdio> #include<cctype> #include<algorithm> #include<queue> #include<map> #include<set> #include<vector> #include<stack> #include<ctime> #include<cstdlib> #include<functional> #include<cmath> using namespace std; #define PI acos(-1.0) #define MAXN 50100 #define eps 1e-7 #define INF 0x7FFFFFFF #define LLINF 0x7FFFFFFFFFFFFFFF #define seed 131 #define MOD 1000000007 #define ll long long #define ull unsigned ll #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 struct node{ int u,v,next; }edge[MAXN]; int head[20],vis[20],in[20],mapp[10][10]; int n,cnt; string win[20] = {"1","12","23","3","14","1245","2356","36","47","4578","5689","69","7","78","89","9"}; void add_edge(int a,int b){ edge[cnt].u = a; edge[cnt].v = b; edge[cnt].next = head[a]; head[a] = cnt++; } void build_graph(){ int i,j; int tot = 0; for(i=1;i<=4;i++){ for(j=1;j<=4;j++){ for(int ii=0;ii<win[tot].length();ii++){ if(win[tot][ii]-'0'==mapp[i][j]) continue; if(vis[win[tot][ii]-'0']){ in[win[tot][ii]-'0']++; add_edge(mapp[i][j],win[tot][ii]-'0'); } } tot++; } } } bool toposort(){ int i; queue<int>q; for(i=1;i<10;i++){ if(!in[i]&&vis[i]) q.push(i); } int sum = 0; while(!q.empty()){ int u = q.front(); q.pop(); sum++; for(i=head[u];i!=-1;i=edge[i].next){ int next = edge[i].v; in[next]--; if(in[next] == 0) q.push(next); } } if(sum==n) return true; return false; } int main(){ int i,j; char str[20]; while(scanf("%s",str),strlen(str)<6){ memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); memset(in,0,sizeof(in)); n = cnt = 0; for(i=1;i<=4;i++){ for(j=1;j<=4;j++){ scanf("%d",&mapp[i][j]); if(!vis[mapp[i][j]]) n++; vis[mapp[i][j]] = 1; } } scanf("%s",str); build_graph(); if(toposort()) printf("THESE WINDOWS ARE CLEAN\n"); else printf("THESE WINDOWS ARE BROKEN\n"); } return 0; }
标签:拓扑排序
原文地址:http://blog.csdn.net/zzzz40/article/details/38847763