之前没整理拓扑排序,这里记一下。
模板一:方便理解原理,但效率低
const int maxn=100+7;
int n,m;
int a[maxn][maxn],c,in[maxn],b[maxn];
void tp(){
for(int i=1;i<=n;i++){
int x;
for(int j=1;j<=n;j++)
if(!in[j]){
x=j; in[j]--;
b[c++]=j; break;
}
for(int j=1;j<=n;j++) if(a[x][j]) in[j]--;
}
}
int main(){
n=read(); m=read();
while(m--){
int x,y; x=read(); y=read();
a[x][y]++; in[y]++;
}
tp();
if(c==n) for(int i=0;i<c;i++) cout<<b[i]<<' ';
}
/*
6 8
1 2
1 4
1 3
3 2
3 5
6 4
4 5
6 5
1 3 2 6 4 5
*/
模板二:常用,复杂度O(V+E),点数加边数
也可以用上面的数据验证,如果要字典序排序,改成优先队列即可。
int n,m,c,in[maxn],b[maxn];
vector<int>a[maxn];
void tp(){
queue<int>q;
for(int i=1;i<=n;i++) if(!in[i]) q.push(i);
while(!q.empty()){
int x=q.front(); q.pop(); b[c++]=x;
for(int i=0;i<a[x].size();i++){
int y=a[x][i]; in[y]--;
if(!in[y]) q.push(y);
}
}
}
int main(){
n=read(); m=read();
while(m--){
int x,y; x=read(); y=read();
a[x].push_back(y); in[y]++;
}
tp();
if(c==n) for(int i=0;i<c;i++) cout<<b[i]<<' ';
}
题目链接:Sorting It All Out
emmm,题目意思有点长,不弄题意了。
这里也可以用模板二的,但是也要判断q.size与1的关系,还是要遍历一般,这数据也就26,不大,用模板一暴力跑了一遍。
这题的关键是进一步理解拓扑排序,什么时候出现环,什么时候有多种排序。
int n,m,in[30],a[30][30],b[30],c,k;
int flag,t,f[30];
int tp(){
c=0; int v=1;
int temp[30]; for(int i=0;i<n;i++) temp[i]=in[i];
for(int i=0;i<n;i++){
int x=0,y=0;
for(int j=0;j<n;j++){
if(!temp[j]){
x++;
y=j;
}
}
if(!x) return 2;
if(x>1) v=0;
b[c++]=y; temp[y]=-1;
for(int i=0;i<n;i++) if(a[y][i]) temp[i]--;
}
return v;
}
int main(){
while(cin>>n>>m&&(n+m)){
t=flag=0; memset(in,0,sizeof(in)); memset(a,0,sizeof(a));
for(int i=1;i<=m;i++){
string sz; cin>>sz;
if(flag) continue;
int x=sz[0]-'A'; int y=sz[2]-'A';
if(a[x][y]) continue;
a[x][y]=1; in[y]++;
t=tp();
if(t==2) flag=2,k=i;
else if(t==1) flag=1,k=i;
}
if(flag==1){
printf("Sorted sequence determined after %d relations: ",k);
for(int i=0;i<n;i++) printf("%c",b[i]+'A');
putchar('.'); putchar('\n');
}
else if(flag==2) printf("Inconsistency found after %d relations.\n",k);
else printf("Sorted sequence cannot be determined.\n");
}
}