http://poj.org/problem?id=2367
题意:一个关系比较混乱的部落,输出按照辈分排序输出。
题解:拓扑排序裸题;
拓扑排序三步:
1.选取没有前驱的节点输出
2.删去这个节点出发的边(也就是终点入度-1)
3.重复1,2。直到所有点输出完毕,或者剩下的点都有前驱为止。(若剩下的点都有前驱则有环);
代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int mp[105][105],indegree[105];
int n;
void topusort(){
int i,j;
int mark;
queue<int> que;
for(i=0;i<n;i++){
for(j=0;j<n;j++){
if(indegree[j]==0){
mark=j;
break;
}
}
indegree[mark]=-1;
que.push(mark);
for(j=0;j<n;j++){
if(mp[mark][j])indegree[j]--;
}
}
while(!que.empty()){
printf("%d",que.front()+1);
que.pop();
if(que.empty())printf("\n");
else printf(" ");
}
}
int main()
{
int i;
int m;
while(~scanf("%d",&n)){
memset(mp,0,sizeof(mp));
memset(indegree,0,sizeof(indegree));
for(i=0;i<n;i++){
while(scanf("%d",&m),m){
m--;
mp[i][m]=1;
indegree[m]++;
}
}
topusort();
}
// cout << "Hello world!" << endl;
return 0;
}
HDU1285 给出成绩大小关系,确定成绩排序。注意这里的大小关系可能重复,加入边的时候,要检查这条边是不是已经存在。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int mp[505][505],indegree[505];
int n;
void topusort(){
int i,j;
int mark;
queue<int> que;
for(i=0;i<n;i++){
for(j=0;j<n;j++){
if(indegree[j]==0){
mark=j;
break;
}
}
indegree[mark]=-1;
que.push(mark);
for(j=0;j<n;j++){
if(mp[mark][j])indegree[j]--;
}
}
while(!que.empty()){
printf("%d",que.front()+1);
que.pop();
if(que.empty())printf("\n");
else printf(" ");
}
}
int main()
{
int i;
int m;
int a,b;
while(~scanf("%d%d",&n,&m)){
memset(mp,0,sizeof(mp));
memset(indegree,0,sizeof(indegree));
for(i=0;i<m;i++){
scanf("%d%d",&a,&b);
a--,b--;
if(mp[a][b])continue;
mp[a][b]=1;
indegree[b]++;
}
topusort();
}
// cout << "Hello world!" << endl;
return 0;
}