我居然要讲课了!!我这么水,啧啧。。好好准备呀。。要不就死定了。。
这道题,典型的拓扑排序,n个字母,操作m次,然后看看对不对。
看了好久才懂,我真是水呀。。
题解:
每输入一组条件,就进行一次拓扑排序,看看符不符合,在topsort函数中,先循环n次,目的把所有入度为零的点都找到并操作,在每次循环里,先看看有几个入度为零的点。
若没有,必存在环,因为每个点入度数组初始化为零,如果真存在环了,行了,就可以说他Inconsistency found了。
若有多个入度为零的点,那么这个图的关系还是不明确的,返回-1,让主函数继续接收信息。
若n个循环都顺利进行完了,flag2也不是-1,那么根据flag2的初始化,他被赋为了1,那么返回1,主函数中输出这一切,表示我们找到了。
flag1的作用主要是找没找到,找到了赋为1,以后即使接收了信息也不拓扑排序了。
这道题呀,如果2 2A<B B<A 是不报错的。。
ps:对于3 2 A<B B<A这个样例,虽然到第二次操作的时候in[C-'A']为零,但是接着循环的时候就会发现有环了。。
#include<stdio.h>
#include<string.h>
int n,m,map[30][30],in[30],q,flag1,it[30];
int topsort()
{
int incy[30];
int flag2=1,k=0;
for(int i=0;i<n;i++)
incy[i]=in[i];
for(int i=0;i<n;i++)
{
int p=0,now;
for(int j=0;j<n;j++)
{
//printf("incy[%d]=%d n=%d\n",j,incy[j],n);
if(!incy[j])
{
now=j;
p++;
//printf("now=%d p=%d\n",now,p);
}
}
if(p==0) //cycle
return 0;
if(p>1) //not know it, let's continue
flag2=-1;
incy[now]=-1;
it[k++]=now;
for(int j=0;j<n;j++)
{
if(map[now][j])
incy[j]--;
}
}
return flag2;
}
int main()
{
while(scanf("%d%d",&n,&m)&&(n||m))
{
memset(map,0,sizeof(map));
memset(in,0,sizeof(in));
flag1=0;
for(int i=0;i<m;i++)
{
//printf("n=%d m=%d \n",n,m);
char s[5];
scanf("%s",s);
map[s[0]-'A'][s[2]-'A']=1;
in[s[2]-'A']++;
if(!flag1)
q=topsort();
if(q==1&&!flag1)
{
printf("Sorted sequence determined after %d relations: ",i+1);
for(int j=0;j<n;j++)
printf("%c",it[j]+'A');
printf(".\n");
flag1=1;
}
if(!q&&!flag1)
{
printf("Inconsistency found after %d relations.\n",i+1);
flag1=1;
}
}
if(!flag1)//所有都结束了 还没被标记,行了。。找不到了
printf("Sorted sequence cannot be determined.\n");
}
return 0;
}