原题链接:
题目大意:
Sample Input
5//n–以下输入n行条件,此题共n个点
0
4 5 1 0//输入若干个数,输入的数以0作为结尾,输入的若干数输出 顺序都排在i的后面**i表示第i行
1 0
5 3 0
3 0
Sample Output
2 4 5 3 1//输出符合题意的排序
思路: >o<
裸的拓扑排序 >o<
如果i排在j之后,那么就代表从i到j有一条边 >o<
然后,然后,就排序就好了 >o<
** >o<
首先贴一个比较low的代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=100+10;
bool a[maxn][maxn];//记录i到j是否有边
bool vis[maxn];//记录i是否已经放入结果集合
int cont[maxn];//记录i的入度个数
int n;
int lis[maxn];//记录拓扑顺序
void topo_sort(){
int k=0;
while(k!=-1){
for(int i=1;i<=n;i++){
if(cont[i]==0&&!vis[i]){
lis[++k]=i;
vis[i]=true;//将i放入结果集合
for(int j=1;j<=n;j++){
if(a[i][j]){
a[i][j]=false;//将与i相连的边去掉
cont[j]--;
}
}
}
}
if(k==n)
break;
}
for(int i=1;i<=n;i++)
printf("%d ",lis[i]);
}
int main(){
scanf("%d",&n);
memset(a,false,sizeof(a));
memset(vis,false,sizeof(vis));
memset(cont,0,sizeof(cont));
for(int i=1,l;i<=n;i++){
while(scanf("%d",&l)&&l!=0){
a[i][l]=true;
cont[l]++;
}
}
topo_sort();
return 0;
}
再贴一个用queue优化的代码 >o<
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int maxn=100+10;
struct N{
int to[maxn];
}node[maxn];//node[i].to[cnt]=j代表i到j有边
int n;
int siz[maxn];//记录每个点所连的边个数
int cont[maxn];//记录每个点的入度个数
void topo_sort(){
queue <int> pq;
for(int i=1;i<=n;i++){
if(cont[i]==0)
pq.push(i);//入度为0的点入队
}
while(!pq.empty()){
int l=pq.front();//弹出队首
pq.pop();
printf("%d ",l);
for(int j=1;j<=siz[l];j++){
int ll=node[l].to[j];//更新与队首有关的点的入度
cont[ll]--;
if(cont[ll]==0)
pq.push(ll);
}
}
}
int main(){
scanf("%d",&n);
int l;
memset(cont,0,sizeof(cont));
for(int i=1;i<=n;i++){
int cnt=0;
while(scanf("%d",&l)&&l!=0){
node[i].to[++cnt]=l;
cont[l]++;
}
siz[i]=cnt;
}
topo_sort();
return 0;
}
**>o<
**>o<