hdu 1811 拓扑排序+并查集+细心

题意和方法都很简单,只是需要注意的地方很多,例如加边时起点终点可能在一个集合内,还有既冲突也不全的情况优先判断冲突。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <queue>
  5 using namespace std;
  6 
  7 const int N = 10000;
  8 const int M = 20000;
  9 int f[N];
 10 int head[N];
 11 int in[N];
 12 int n, m, e, sum;
 13 
 14 int findf( int x )
 15 {
 16     if ( f[x] != x ) f[x] = findf(f[x]);
 17     return f[x];
 18 }
 19 
 20 void union_set( int x, int y )
 21 {
 22     x = findf(x), y = findf(y);
 23     if ( x != y )
 24     {
 25         f[x] = y;
 26     }
 27 }
 28 
 29 struct Op
 30 {
 31     int a, b;
 32     char r[2];
 33 } op[M];
 34 
 35 struct Edge 
 36 {
 37     int v, next;
 38 } edge[M];
 39 
 40 void addEdge( int u, int v )
 41 {
 42     edge[e].v = v;
 43     edge[e].next = head[u];
 44     head[u] = e++;
 45 }
 46 
 47 int main ()
 48 {
 49     while ( scanf("%d%d", &n, &m) != EOF )
 50     {
 51         e = 0;
 52         sum = n;
 53         memset( head, -1, sizeof(head) );
 54         memset( in, 0, sizeof(in) );
 55         for ( int i = 0; i < n; i++ ) f[i] = i;
 56         for ( int i = 0; i < m; i++ )
 57         {
 58             scanf("%d%s%d", &op[i].a, op[i].r, &op[i].b);
 59             if ( op[i].r[0] == '=' )
 60             {
 61                 sum--;
 62                 union_set( op[i].a, op[i].b );
 63             }
 64         }
 65         bool flag0 = false;
 66         for ( int i = 0; i < m; i++ )
 67         {
 68             if ( op[i].r[0] == '=' ) continue;
 69             int a = findf(op[i].a), b = findf(op[i].b);
 70             if ( a == b )
 71             {
 72                 flag0 = true;
 73                 break;
 74             }
 75             if ( op[i].r[0] == '<' )
 76             {
 77                 addEdge( b, a );
 78                 in[a]++;
 79             }
 80             else
 81             {
 82                 addEdge( a, b );
 83                 in[b]++;
 84             }
 85         }
 86         if ( flag0 )
 87         {
 88             puts("CONFLICT");
 89             continue;
 90         }
 91         queue<int> q;
 92         for ( int i = 0; i < n; i++ )
 93         {
 94             if ( !in[i] && f[i] == i ) q.push(i);
 95         }
 96         bool flag1 = false;
 97         while ( !q.empty() )
 98         {
 99             if ( q.size() > 1 ) flag1 = 1;
100             int u = q.front();
101             q.pop();
102             sum--;
103             for ( int i = head[u]; i != -1; i = edge[i].next )
104             {
105                 int v = edge[i].v;
106                 in[v]--;
107                 if ( in[v] == 0 )
108                 {
109                     q.push(v);
110                 }
111             }
112         }
113         if ( sum > 0 )
114         {
115             puts("CONFLICT");
116         }
117         else
118         {
119             if ( flag1 ) puts("UNCERTAIN");
120             else puts("OK");
121         }
122     }
123     return 0;
124 }
原文地址:https://www.cnblogs.com/huoxiayu/p/4705235.html