POJ 1094 Sorting It All Out 拓扑排序 +floyd!
题意很容易理解,就是拓扑排序 实现起来不容易,起码我觉得是这样
首先 用拓扑排序检查是否有环 如果没环路 再用floyd传递闭包 (传递闭包 好专业的术语喔),再判断序列是否唯一
学了一下拓扑排序,不难,就是先算出每个点的入度 ,找出入度为0 ,比如 i 作为第一个,然后比如map[i][j]==1 i,j 之间存在 i->j的边
则从cnt[j]--,即 j 的入度减一 然后再找入度为0的点。。。
floyd传递闭包 判断序列是否唯一的方法!
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
int map[30][30],visit[30],cnt[30],path[30];
int n;
bool topsort()
{
int i,j,k;
memset(cnt,0,sizeof(cnt));
for(i=0;i<n;i++)
for(j=0;j<n;j++)
cnt[j]+=map[i][j];
for(i=0;i<n;i++)
{
for(k=0;k<n;k++)
if(cnt[k]==0)break;
if(k==n)return false;//有环
for(j=0;j<n;j++)
if(map[k][j])cnt[j]--;
path[i]=k;
cnt[k]-=1;
}
return true;
}
int main()
{
int m,t,i,j,k;
char ch[5];
bool output;
while(~scanf("%d%d",&n,&m))
{
output=false;
if(n==0&&m==0)break;
memset(map,0,sizeof(map));
for(t=1;t<=m;t++)
{
scanf("%s",&ch);
if(output)continue;//只需输入
i=ch[0]-'A';
j=ch[2]-'A';
if(map[i][j])continue;//如果已经判断过 无需重复
map[i][j]=1;
if(!topsort())//如果有环
{
printf("Inconsistency found after %d relations.\n",t);
output=true;
continue;
}
for(k=0;k<n;k++)
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(map[i][k]&&map[k][j])
map[i][j]=1;
bool visit[30],flag=true;
memset(visit,0,sizeof(visit));//开始还漏了WA
int SUM;
for(i=0;i<n;i++)
{
SUM=0;
for(j=0;j<n;j++)
{
if(map[i][j])
SUM++;
}
if(visit[SUM]){flag=false; break;}
visit[SUM]=true;
}
if(flag)
{
printf("Sorted sequence determined after %d relations: ",t);
for(i=0;i<n;i++)
printf("%c",path[i]+'A');
printf(".\n");
output=true;
}
}
if(!output)
printf("Sorted sequence cannot be determined.\n");
}
return 0;
}

浙公网安备 33010602011771号