這一題,看了個大牛的解題報告,思路變得非常的清晰:
1,先利用floyd_warshall算法求出圖的傳遞閉包
2,再判斷是不是存在唯一的拓撲排序,利用出度和入度是不是相加為n-1
3,利用拓撲排序求出當前的圖形的唯一的拓撲排序
一開始我的思路跟上述的差不多,但是沒有利用floyd_warshall算法求出傳遞閉包,准備著利用拓撲排序求出是不是存在著有環回路,我覺得我的這個思路也是可以的。等一下我會將我的這個思路給寫成程序。在我的百度雲中有這個程序的測試數據(來自poj)
#include <iostream>
//#include <fstream>
using namespace std;
#define MAX 30
/*396K 16MS*/
//var
int a[MAX][MAX];
int n;
int flag1,flag2; //falg1代表的是當前有環的錯誤,即存在錯誤的排序
char s[MAX]; //存放最後的結果
//fstream fin;
//function
bool transition();
bool judge();
void toposort();
//main函數
int main()
{
//fin.open("1094.txt",ios::in);
int m;
while(cin>>n>>m)
{
if(n==0&&m==0) break;
memset(a,0,sizeof(a));
int count=1;
flag1=flag2=false;
for(int i=0;i<m;i++)
{
char b1,b2;
cin>>b1>>b2>>b2;
if(flag1||flag2) continue;
if(a[b1-'A'][b2-'A']==0)
{
a[b1-'A'][b2-'A']=1;
//求傳遞閉包,判斷是不是有環,這樣就知道是不是存在著錯誤的答案
if(!transition()){flag1=true;continue;}
//判斷是不是存在著唯一的拓撲排序
else if(judge())
{
toposort();
flag2=true;
continue;
}
}
++count;
}
if(flag1)
cout<<"Inconsistency found after "<<count<<" relations."<<endl;
else if(flag2)
cout<<"Sorted sequence determined after "<<count<<" relations: "<<s<<"."<<endl;
else
cout<<"Sorted sequence cannot be determined."<<endl;
}
system("pause");
return 0;
}
//求傳遞閉包
bool transition()
{
for(int k=0;k<n;k++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(a[i][j]==1||a[i][k]==1&&a[k][j]==1)
a[i][j]=1;
for(int i=0;i<n;i++)
if(a[i][i]==1)
return false;
return true;
}
//計算是不是存在著唯一的拓撲排序
bool judge()
{
int *ind=new int[n];
int *outd=new int[n];
memset(ind,0,sizeof(int)*n);
memset(outd,0,sizeof(int)*n);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(a[i][j])
{
ind[j]++;
outd[i]++;
}
}
}
for(int i=0;i<n;i++)
if(ind[i]+outd[i]<n-1)
return false;
return true;
}
//拓撲排序的實現
void toposort()
{
//按照入度來進行計算
int *ind=new int[n];
memset(ind,0,sizeof(int)*n);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
if(a[i][j]==1)
ind[j]++;
}
//求出入度後計算出當前的的拓撲排序的結果
int t=n;
for(int i=0;i<n;i++)
{
int j;
for(j=0;j<n;j++)
if(ind[j]==0)
{ ind[j]--; s[i]=j+'A'; break;}
int t=j;
for(j=0;j<n;j++)
if(a[t][j]==1)
ind[j]--;
}
s[n]='\0';
}