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