POJ 1094解题报告
这个题主要的是使用拓扑排序,相关算法随便找一本算法的书都能看到,也不难,就不罗嗦了。
我使用邻接表来保存图,并使用dm,dn分别保存每个节点(即字母)的出度和入度。
我只想强调一下需要注意的:
一、先判断是否有环路
我就是一开始在检测到不能确定序列的时候就直接返回了,而没有判断是否有环路,结果一直WA;
二、当序列可以确定或是检测到环路的时候,忽略后边的输入。
- #include<iostream>
- #include<fstream>
- using namespace std;
- char G[26][26];
- int dm[26]; //每一列的和,即每个字母的入度
- int dn[26]; //每一行的和,即每个字母的出度
- int m,n;
- char result[27];
- int TopoSort()
- {
- int index; //起点
- int r = 0;
- int count;
- bool sorted = true;
- int dmt[26];
- int dnt[26];
- memcpy(dmt,dm,sizeof(dmt));
- memcpy(dnt,dn,sizeof(dnt));
- //找出入度为零的点
- for(int j=0;j<n;j++)
- {
- count = 0;
- for(int i=0;i<n;i++)
- {
- if(0 == dmt[i])
- {
- index = i;
- count++;
- }
- }
- if(0 == count) //发现环路
- return count;
- if(count > 1) sorted = false;
- for(int i=0;i<dnt[index];i++)
- {
- dmt[G[index][i]-'A']--;
- }
- dmt[index] = -1;
- result[r++] = index + 'A';
- }
- result[r] = 0;
- if(sorted)
- return 1; //序**定
- else
- return 2; //序列不确定
- }
- int main()
- {
- int i,j,k;
- char str[4];
- //ifstream in("data.in");
- cin>>n>>m;
- while(n&&m)
- {
- k = 0;
- int found = 0; //可以完全确定序列
- int incons = 0; //发现冲突,即环路
- memset(dm,0,sizeof(dm));
- memset(dn,0,sizeof(dn));
- memset(G,0,sizeof(G));
- for(i=0;i<m;i++)
- {
- cin>>str;
- if(!found && !incons)
- {
- for(j=0;j<dn[str[0]-'A'];j++)
- {
- if(G[str[0]-'A'][j] == str[2])
- break;
- }
- if(j == dn[str[0]-'A'])
- {
- G[str[0]-'A'][j] = str[2];
- dm[str[2]-'A'] ++;
- dn[str[0]-'A'] ++;
- }
- int res = TopoSort();
- if(1 == res) //序列已确定
- {
- found = i+1;
- }
- else if(0 == res) //发现冲突
- {
- incons = i+1;
- }
- }
- }
- if(found)
- {
- cout<<"Sorted sequence determined after "<<found<<" relations: "<<result<<"."<<endl;
- }
- else if(incons)
- {
- cout<<"Inconsistency found after "<<incons<<" relations."<<endl;
- }
- else
- {
- cout<<"Sorted sequence cannot be determined."<<endl;
- }
- cin>>n>>m;
- }
- return 0;
- }