首页 > 代码库 > POJ--2585--Window Pains【拓扑排序】

POJ--2585--Window Pains【拓扑排序】

链接: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;
}



POJ--2585--Window Pains【拓扑排序】