POJ 1094解题报告
这个题主要的是使用拓扑排序,相关算法随便找一本算法的书都能看到,也不难,就不罗嗦了。
我使用邻接表来保存图,并使用dm,dn分别保存每个节点(即字母)的出度和入度。
我只想强调一下需要注意的:
一、先判断是否有环路
我就是一开始在检测到不能确定序列的时候就直接返回了,而没有判断是否有环路,结果一直WA;
二、当序列可以确定或是检测到环路的时候,忽略后边的输入。
- #include<iostream>
- #include<fstream>
- usingnamespacestd;
- charG[26][26];
- intdm[26];//每一列的和,即每个字母的入度
- intdn[26];//每一行的和,即每个字母的出度
- intm,n;
- charresult[27];
- intTopoSort()
- {
- intindex;//起点
- intr=0;
- intcount;
- boolsorted=true;
- intdmt[26];
- intdnt[26];
- memcpy(dmt,dm,sizeof(dmt));
- memcpy(dnt,dn,sizeof(dnt));
- //找出入度为零的点
- for(intj=0;j<n;j++)
- {
- count=0;
- for(inti=0;i<n;i++)
- {
- if(0==dmt[i])
- {
- index=i;
- count++;
- }
- }
- if(0==count)//发现环路
- returncount;
- if(count>1)sorted=false;
- for(inti=0;i<dnt[index];i++)
- {
- dmt[G[index][i]-'A']--;
- }
- dmt[index]=-1;
- result[r++]=index+'A';
- }
- result[r]=0;
- if(sorted)
- return1;//序**定
- else
- return2;//序列不确定
- }
- intmain()
- {
- inti,j,k;
- charstr[4];
- //ifstreamin("data.in");
- cin>>n>>m;
- while(n&&m)
- {
- k=0;
- intfound=0;//可以完全确定序列
- intincons=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']++;
- }
- intres=TopoSort();
- if(1==res)//序列已确定
- {
- found=i+1;
- }
- elseif(0==res)//发现冲突
- {
- incons=i+1;
- }
- }
- }
- if(found)
- {
- cout<<"Sortedsequencedeterminedafter"<<found<<"relations:"<<result<<"."<<endl;
- }
- elseif(incons)
- {
- cout<<"Inconsistencyfoundafter"<<incons<<"relations."<<endl;
- }
- else
- {
- cout<<"Sortedsequencecannotbedetermined."<<endl;
- }
- cin>>n>>m;
- }
- return0;
- }
本文介绍了解决POJ1094问题的方法,采用拓扑排序算法,并使用邻接表保存图数据结构。文章详细展示了如何通过检测环路来确定字母排序序列是否唯一确定,以及如何在检测到冲突时进行处理。
1334

被折叠的 条评论
为什么被折叠?



