poj 1094 Sorting It All Out

 1 #include<iostream>
2 #include<cstring>
3 #include<stack>
4 using namespace std;
5 #define N_MAX 27
6
7 bool map[N_MAX][N_MAX];
8 int indegree[N_MAX];
9 int outdegree[N_MAX];
10 int n,m;
11 char str[N_MAX];
12 bool floyd()
13 {
14 for(int k=0;k<n;++k)
15 for(int i=0;i<n;++i)
16 for(int j=0;j<n;++j)
17 if(map[i][k]&&map[k][j]) map[i][j]=true;
18 //根据map[t][t]判断是否有环出现
19 for(int t=0;t<n;++t)
20 if(map[t][t]) return false;
21 return true;
22
23 }
24
25 bool IsDetermined()
26 {
27 //根据每个点的出度和入度之和是否是n-1
28 int i,j;
29 memset(indegree,0,sizeof(indegree));
30 memset(outdegree,0,sizeof(outdegree));
31 for(i=0;i<n;++i)
32 {
33 for(j=0;j<n;++j)
34 if(map[i][j]) {++indegree[j],++outdegree[i];}
35 }
36
37 //判断
38 for(i=0;i<n;++i)
39 if(indegree[i]+outdegree[i]!=n-1) return false;
40 return true;
41 }
42
43 void topologicalSort()
44 {
45 int i,j=0;
46 stack<int> st;
47 memset(str,0,sizeof(str));
48 //首先找到第一个入度为零的节点
49 //bool mark[N_MAX]={false};
50 for(i=0;i<n;i++)
51 if(indegree[i]==0) st.push(i);
52 //mark[i]=true;
53 while(!st.empty())
54 {
55 int t=st.top();
56 str[j++]=t+'A';
57 st.pop();
58 for(i=0;i<n;++i)
59 if(map[t][i]==true && !(--indegree[i]))//&& mark[i]==false)
60 st.push(i);
61 }
62 str[j]='\0';
63 }
64 int main()
65 {
66 char buf[5];
67 int Inconsistency,Determined;
68
69 //freopen("a.txt","r",stdin);
70 while(cin>>n>>m,n||m)
71 {
72 Inconsistency=Determined=0;
73 memset(map,false,sizeof(map));
74 for(int i=1;i<=m;++i)
75 {
76 //输入信息,
77 cin>>buf;
78 map[buf[0]-'A'][buf[2]-'A']=true;
79 //用floyd算法,计算闭包,判断是否存在环
80 if(Inconsistency || Determined) continue;
81 else if(!floyd())
82 {//当出现环时
83 Inconsistency=i;
84 }
85 else if(IsDetermined())
86 {//当顺序确定时
87 //用拓扑排序输出线性序列
88 topologicalSort();
89 Determined=i;
90 }
91 }
92 if(Inconsistency) printf("Inconsistency found after %d relations.\n",Inconsistency);
93 else if(Determined) printf("Sorted sequence determined after %d relations: %s.\n",Determined,str);
94 else printf("Sorted sequence cannot be determined.\n");
95 }
96 return 0;
97 }


题目信息:http://poj.org/problem?id=1094

方法:

 拓扑排序 每次读入一对关后,做一次floyd, 计算传递闭包. 然后判环,其实很简单,就是看有没有点i的map[i][i]=1; 有就证明有环!如果有环就矛盾了。 如果无环再判断是否能确定关系,(注意每次都把出入度数组清零!)计算每个点的出度+入度是否=n-1; 如果所有点都有这个关系,那么唯一的关系就确定了,接下来拓扑排序就能找出这个关系.

 

posted @ 2012-04-01 11:13  AndyDHG  阅读(148)  评论(0编辑  收藏  举报