借鉴y总的思路,但有一点问题:是否可以每次不复制一个新的数组出来做floyd?
个人觉得也没必要,而且评测也可以过
//求传递闭包
//即若存在a->b b->c,则增加a->c
//先初始化使d(i,j)=g(i,j)
//和Floyd算法区别在:更新时若d(i,k)存在且d(k,j)存在,则d(i,j)=1
// i>k k>j i>j
//三种情况:(type值)
// 2:矛盾:d(i,i)=1
// 1:唯一确定:i!=j时d(i,j),d(j,i)必有一个是1
// 0:其他
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 26;
int n, m;
bool g[N][N],d[N][N];//G为边,d为求传递闭包过程
bool st[N];//当前变量有没有被输出
void floyd()
{
memcpy(d,g,sizeof d);//没必要每次复制一个新的出来?
for (int k = 0; k < n; k ++ )
for (int i = 0; i < n; i ++ )
for (int j = 0; j < n; j ++ )
d[i][j] = d[i][j] || (d[i][k] && d[k][j]);
memcpy(g,d,sizeof g);
}
int check(){
for(int i=0;i<n;i++){
if(d[i][i])return 2;
}
for(int i=0;i<n;i++){
for(int j=0;j<i;j++){
if(!d[i][j]&&!d[j][i]){
return 0;
}
}
}
return 1;
}
char get_min(){
for(int i=0;i<n;i++){
if(!st[i]){
bool flag=true;
for(int j=0;j<n;j++){
if(!st[j]&&d[j][i]){
flag=false;//存在比i小的(即存在j->i)
break;
}
}
if(flag){//i是最开头的 (没有人指向它)
st[i]=true;
return 'A'+i;
}
}
}
}
int main()
{
while(cin>>n>>m,n||m){
memset(g,0,sizeof g);
int type=0,t;//t为type第一次从0变成1或2时,迭代的次数
for(int i=1;i<=m;i++){
char str[5];
cin>>str;
int a=str[0]-'A',b=str[2]-'A';
if(!type){
g[a][b]=1;
floyd();
type=check();
if(type)t=i;
}
}
if(!type)puts("Sorted sequence cannot be determined.");
else if(type==2)printf("Inconsistency found after %d relations.\n",t);
else{
memset(st,0,sizeof st);
printf("Sorted sequence determined after %d relations: ",t);
for(int i=0;i<n;i++)printf("%c",get_min());
printf(".\n");
}
}
return 0;
}