SortingItAllOutPOJ-1094拓扑排序(唯⼀拓扑序)
题⽬⼤意:给两个整数n, m, n表⽰从A到第n个字母,然后给m个偏序关系,求⽤到第⼏个偏序关系就可以求得唯⼀的拓扑序列,(注意:是唯⼀的拓扑序列),
1. 如果可以求得唯⼀拓扑序列,则输出⽤到第⼏个偏序关系就可以求出,并输出序列。
2. 如果不能确定唯⼀的拓扑序列,输出要求的语句
3. 如果有⽭盾的偏序关系,输出从第⼏个开始的
题⽬分析:⽐较值得注意的就是唯⼀的拓扑序列,我们知道,偏序关系不全的时候拓扑序列是不唯⼀的,因此需要改进。⽤拓扑排序可以知道这个元素后⾯的所有元素,那么这个元素的位置就是前⾯元素中最前⾯的再前⼀个。也就是它必须位于所有他后⾯元素的前⼀个。全部这样处理之后,如果有位置不确定就就会被覆盖掉,如果求完所有的元素之后,下标为0的地⽅也有了元素,证明这个序列是唯⼀的。
举个栗⼦:假设有5个字母(ABCDE),偏序关系为 A < D; 拓扑排序的时候我们计算到A的时候要在D的前⼀个,⽽D后⾯没有元素,则D的位置为 4, A的位置则为3,再计算B的时候位置为4;这样求完所有的元素,位置都在3和4上,就不会求到0,所以他的序列不唯⼀,如果按照字典序, A就在0位置,序列唯⼀。
冬虫夏草怎么辨别
然后再解决第⼆个问题,什么时候偏序关系⽭盾,这是拓扑排序本来就能求得,如果⽭盾了返回下标-1标记即可。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
typedef pair<int, int> P;
const int INF = 1 << 31 -1;
int n, m;
P E[1000];
vector<int> TO[30];
int topo[30], pos[30], vis[30];
int topo_sort(int v)
{
if(vis[v] == -1) return -1; //存在有相环,偏序关系冲突
if(pos[v] != -1) return pos[v];社区自治
vis[v] = -1;
int p = n;
int size = TO[v].size();
for(int i=0; i<size; ++i)
{
p = min(p, topo_sort(TO[v][i]));
}
if(p == -1) return -1;
topo[p-1] = v;
pos[v] = p-1;
vis[v] = 0;
return p-1;
}
int main()
{
char s[100];
while(scanf("%d%d", &n, &m) && n+m)
{
for(int i=0; i<n; ++i)
{
小学教资考试时间TO[i].clear();
}
for(int i=0; i<m; ++i)
{
scanf("%s", s);
E[i] = P(s[0]-'A', s[2]-'A');
}
int ans = n;
雪糕制作
for(int i=0; i<m; ++i)
{
P p = E[i];
TO[p.first].push_d);
ans = n;
memt(vis, 0, sizeof vis);
memt(pos, -1, sizeof pos);
昔者庄周梦为蝴蝶for(int j=0; j<n; ++j)
ans = min(ans, topo_sort(j));
if(ans == -1)
复调
{
printf("Inconsistency found after %d relations.\n", i+1);
break;
钱怎么折爱心}
el if(ans == 0)
{
rpm是什么单位printf("Sorted quence determined after %d relations: ", i+1); for(int j=0; j<n; ++j) printf("%c", topo[j]+'A');
printf(".\n");
break;
}
}
if(ans > 0) printf("Sorted quence cannot be determined.\n"); }
return 0;
}