Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1109    Accepted Submission(s): 275

       本题对本人来说绝对是一个挑战,因为以前我从来没有写过拓扑排序也没用过set,这是我第一次的尝试,虽然wrong了很多次花费了一整天的时间,但还是应当值得纪念的。本题的思想就是拓扑排序+并查集。

     注意事项:

    (1)因为本题数据比较大,用邻接矩阵存储太浪费空间了,我就因此而超内存好几次,建议使用邻接表。特别是对这种稀疏矩阵,采用邻接表即可节约空间又可节约时间

     (2)一定要找完才能判断,如果同时又CONFLICT和UNCERTAIN输出CONFLICT

     (3)使用并查集一定要小心,如果对某个节点操作一定要转化为对根节点的操作,因为本题的思想就是用并查集把相同放到一个集合看成是一个节点。

  代码:

  

 

1 #include<iostream>
2 #include<set>
3  using namespace std;
4 typedef struct t
5 {
6 int data;
7 struct t *next;
8 }T;
9  struct node
10 {
11 int in;
12 int root;
13 struct t *next;
14 bool operator <(const node &a) const
15 {
16 if(a.in == in)
17 return a.root > root;
18 else return a.in > in;
19 }
20 }s[10005];
21  int father[10005],rank[10005],a1[10005],c1[10005];char d[10005];
22  void insert(int a,int c)
23 {
24 node * t=&s[a];
25 T * x=(T *)malloc(sizeof(T));
26 s[c].in++;
27 x->data=c;
28 x->next=t->next;
29 t->next=x;
30 }
31 int find(int x)
32 {
33 if(x!=father[x])
34 father[x]=find(father[x]);
35 return father[x];
36 }
37 void Union(int x,int y)
38 {
39 x=find(x);
40 y=find(y);
41 if(x==y)
42 return ;
43 if(rank[x]>rank[y])
44 {
45 father[y]=x;
46 }
47 else
48 {
49 if(rank[x]==rank[y])
50 rank[y]++;
51 father[x]=y;
52 }
53 }
54 int main()
55 {
56 set<node> se;
57 node cur1,cur2;
58 int n,m,i,a,c,k,j,mark1,mark2;char b;
59 while(scanf("%d%d",&n,&m)!=EOF)
60 {
61 j=0;
62 se.clear ();
63 for(i=0;i<n;i++)
64 {
65 father[i]=i;
66 s[i].in=0;
67 s[i].next=NULL;
68 s[i].root=i;
69 rank[i]=0;
70 }
71 for(i=1;i<=m;i++)
72 {
73 scanf("%d",&a);
74 getchar();
75 scanf("%c",&b);
76 scanf("%d",&c);
77 if(b=='=')
78 Union(a,c);
79 else
80 {
81 j++;
82 d[j]=b;
83 a1[j]=a;
84 c1[j]=c;
85 }
86 }
87 for(k=1;k<=j;k++)
88 if(d[k]=='>')
89 {
90 a=find(a1[k]);c=find(c1[k]);insert(a,c);
91 }
92 else
93 {
94 a=find(a1[k]);c=find(c1[k]);insert(c,a);
95 }
96
97 for(i=0;i<n;i++)
98 se.insert (s[find(i)]);
99 mark1=0;mark2=0;
100 set<node>::iterator it1;
101 set<node>::iterator it2;
102 while(!se.empty ())
103 {
104 it1=se.begin();
105 if((*it1).in!=0)
106 {
107 mark1=1;
108 cout<<"CONFLICT"<<endl;
109 break;
110 }
111 T * t;
112 t=(*it1).next;
113 se.erase(se.begin ());
114 if(se.empty ())
115 break;
116 it2=se.begin ();
117 if((*it2).in==0)
118 {
119 mark2=1;
120 }
121 while(t!=NULL)
122 {
123 se.erase (s[t->data]);
124 s[t->data].in--;
125 se.insert(s[t->data]);
126 t=t->next;
127 }
128 }
129 if(mark1==0 )
130 if(mark2==1)
131 cout<<"UNCERTAIN"<<endl;
132 else
133 cout<<"OK"<<endl;
134 }
135 return 0;
136 }
137
138
139
140
141
142