POJ 2582 拓扑序列,其实更为准确的说法应该是判是否出现环

这个题我是看书上解题思路做的,自己未必想的出来,就是根据他给你的窗口分布去构造图,比如说这个格子本来可以被1,2,4,5窗口共用(只是指1,2,4,5都能出现在这个格子上,但是一次当然只可能出现一种情况),现在被2占用了,那么2可能是覆盖了1,4,5窗口,这样就构造有向边<2,1>,<2,4>,<2,5>如此类推,把整个图构造出来后,出现环了 ,证明电脑坏掉了,鉴于我相当水,只好用拓扑排序写,因为一共也就9个点,尽管拓扑时间复杂度高,但数据小,也就还能接受啦,不会超时。我0MS过的。

如果可以,建议尽量用别的各种方法去判环。

这题我也WA好多次,这次是因为忘了注释freopen()函数了,各种想自残

贴代码:

View Code
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <string>
 4 using namespace std;
 5 int main()
 6 {
 7     char a[20];
 8     int count[20],mystack[20];
 9     bool visited[12];
10     bool edge[12][12];
11     string cover[4][4] = {{"1","12","23","3"},{"14","1245","2356","36"},
12         {"47","4578","5689","69"},{"7","78","89","9"}
13     };
14 //    freopen("in.cpp","r",stdin);
15     while(~scanf("%s",a))
16     {
17         if(strcmp(a,"ENDOFINPUT") == 0)            break;
18         int w;
19         int c = 0;
20         int cur = 0,cnt = 0;
21         memset(count,0,sizeof(count));
22         memset(visited,false,sizeof(visited));
23         memset(edge,false,sizeof(edge));
24         for(int i=0; i<4; i++)
25         {
26             for(int j=0; j<4; j++)
27             {
28                 scanf("%d",&w);
29                 if(!visited[w])
30                 {
31                     visited[w] = true;
32                     c++;
33                 }
34                 for(int k=0; k< cover[i][j].length(); k++)
35                 {
36                     int t = cover[i][j][k] - '0';
37                     if( t != w && !edge[w][t])
38                     {
39                         if(!visited[t])
40                         {
41                             visited[t] = true;
42                             c++;
43                         }
44                         count[t]++;
45                         edge[w][t] = true;
46                     }
47                 }
48             }
49         }
50         scanf("%s",a);
51         for(int i=1; i<=9; i++)
52         {
53             if(count[i] == 0)
54             {
55                 count[i]--;
56                 mystack[cur++] = i;
57                 cnt++;
58             }
59         }
60         while(cur != 0)
61         {
62             cur--;
63             int t = mystack[cur];
64             for(int k=1; k<=9; k++)
65             {
66                 if(edge[t][k])
67                     count[k]--;
68             }
69             for(int i=1; i<=9; i++)
70             {
71                 if(count[i] == 0)
72                 {
73                     count[i]--;
74                     mystack[cur++] = i;
75                     cnt++;
76                 }
77             }
78         }
79         if(cnt < c) printf("THESE WINDOWS ARE BROKEN\n");
80         else printf("THESE WINDOWS ARE CLEAN\n");
81     }
82     return 0;
83 }
原文地址:https://www.cnblogs.com/allh123/p/2990189.html