Poj Window Pains (拓扑排序) 解题报告

来源:互联网 发布:山东职业学院网络 编辑:程序博客网 时间:2024/06/05 04:33

题目链接:http://dsalgo.openjudge.cn/graph/3/
这道题从思路上讲是一道简单的拓扑排序判断是否存在回路问题,因为如果是正常的屏幕,不会出现几个窗口相互覆盖的情况,比如窗口1覆盖了窗口2,那么窗口2不可能覆盖窗口1。
难点在于细节的处理,就是建图的过程如何处理,我采用的方法是先构造一个表,记录屏幕的每一个位置可能会有哪些窗口占用(最多4个),然后就可以得到节点间关系为被覆盖关系的图。
代码如下:

#include <iostream>#include <queue>#include <string>#include <vector>using namespace std;vector<int> cover[4][4];int iniCover(){    for(int i = 0; i < 9; ++i)    {        int x = i / 3, y = i % 3;         cover[x][y].push_back(i);        cover[x+1][y].push_back(i);        cover[x][y+1].push_back(i);        cover[x+1][y+1].push_back(i);    }}bool link[9][9];void initialize(){    for(int i = 0; i < 9; ++i)        for(int j = 0; j < 9; ++j)            link[i][j] = false;}bool topo(){    int countIn[9];    for(int i = 0; i < 9; ++i)    {        countIn[i] = 0;        for(int j = 0; j < 9; ++j)        {            if(link[j][i])                ++countIn[i];        }    }    int total = 0;    queue<int> que;    for(int i = 0; i < 9; ++i)    {        if(countIn[i] == 0)            que.push(i);    }    while(!que.empty()) {        int now = que.front();        for(int i = 0; i < 9; ++i)        {            if(link[now][i]){                --countIn[i];                if(countIn[i] == 0)                    que.push(i);            }        }        que.pop();        ++total;    }    return total == 9;}int main(){    iniCover();    string line;    int c;    while(cin >> line && line != "ENDOFINPUT") {        initialize();        for(int i = 0; i < 4; ++i)            for(int j = 0; j < 4; ++j)            {                cin >> c;                for(int k : cover[i][j])                {                    if(c-1 != k){                        link[c-1][k] = true;                    }                }            }        bool ans = topo();        if(ans == false)            cout << "THESE WINDOWS ARE BROKEN\n";        else             cout << "THESE WINDOWS ARE CLEAN\n";        cin >> line;    }    return 0;}