思路:
每输入一个关系就拓扑一次
把结果分为三种情况
1.
根据前x个关系得到整体关系
这里我们可以用拓扑把度清零,记录每个字母都出现过
并且判断最长的链是多少就行了
即
f
[
a
[
i
]
.
t
o
]
=
max
(
f
[
a
[
i
]
.
t
o
]
,
f
[
p
[
h
]
]
+
1
)
,
s
=
max
(
s
,
f
[
a
[
i
]
.
t
o
]
)
;
f[a[i].to]=\max(f[a[i].to],f[p[h]]+1),s=\max(s,f[a[i].to]);
f[a[i].to]=max(f[a[i].to],f[p[h]]+1),s=max(s,f[a[i].to]);
如果最长链小于n,那么就没有得到整体关系
2.
根据前x个关系判断是否存在矛盾,
这里只要判断实际就是判断有没有出现环即可。
3.
根据这m个关系无法确定这n个元素的顺序
如果1和2都没有成立,那么就是第3个条件
注意
输入一次就要判断一次a和c是否重复,
因为如果出现
a
<
a
a<a
a<a 这种情况也会出现矛盾
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int d[100010],d2[100010],ls[100010],dl[100010],v[100010],ans[10010],len;
int n,m,tot,hd=0,tl=0;
char aa,b,c;
struct node
{
int y,next;
}a[100010];
void ljb(int x,int y)
{
a[++tot]=(node){y,ls[x]};
ls[x]=tot;
}
void tp()
{
memset(ans,0,sizeof(ans));
memset(v,0,sizeof(v));
hd=0,tl=0,len=0;
for(int i=1; i<=n; i++)
d[i]=d2[i];
for(int i=1; i<=n; i++)
if(d[i]==0)
dl[++tl]=i,v[i]=1,ans[i]=1;
while(hd<tl)
{
hd++;
int y=dl[hd];
for(int i=ls[y]; i; i=a[i].next)
{
int yy=a[i].y;
if(v[yy]==1)
continue;
ans[yy]=max(ans[yy],ans[y]+1);
len=max(len,ans[yy]);
d[yy]--;
if(d[yy]==0)
dl[++tl]=yy,v[yy]=1;
}
}
}
int main()
{
cin>>n>>m;
for(int i=1; i<=m; i++)
{
cin>>aa>>b>>c;
if(aa==c)
{
cout<<"Inconsistency found after "<<i<<" relations.";
return 0;
}
ljb(aa-64,c-64);
d2[c-64]++;
tp();
if(len==n)
{
cout<<"Sorted sequence determined after "<<i<<" relations: ";
for(int j=1; j<=n; j++)
cout<<char(dl[j]+64);
cout<<".";
return 0;
}
for(int j=1; j<=n; j++)
{
if(d[j]!=0)
{
cout<<"Inconsistency found after "<<i<<" relations.";
return 0;
}
}
}
cout<<"Sorted sequence cannot be determined.";
return 0;
}