@Chilling
2017-02-16T17:55:05.000000Z
字数 2468
阅读 1131
拓扑排序
Description
有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。
Input
输入有若干组,每组中的第一行为二个数N,M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。
Output
给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。
其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
Sample Input
4 3
1 2
2 3
4 3
Sample Output
1 2 4 3
拓扑排序:
都是模板
- 从有向图中选取一个没有前驱(即入度为0)的顶点,并输出之;
- 从有向图中删去此顶点以及所有以它为尾的弧;
重复上述两步,直至图空,或者图不空但找不到无前驱的顶点为止。
用二维数组实现,如果数据太多就不行了。
void topsort()
{
int i,j,k=0,c;
for(i=1;i<n+1;i++) //遍历n次
{
for(j=1;j<n+1;j++) //找出入度为0的节点
{
if(in[j]==0) //如果入度为0了
{
in[j]--; //减为-1,下次就不会再找它
ans[k++]=j; //将找到的节点存入数组,其实也可以直接输出
for(c=1;c<n+1;c++) //删除与该节点关联的边
{
if(ma[j][c]==1)
in[c]--;
}
break;
}
}
}
}
#include<stdio.h>
#include<algorithm>
#include<string.h>
int ma[505][505],in[505],ans[505],n,m;
void topsort()
{
int i,j,k=0,c;
for(i=1;i<n+1;i++) //遍历n次
{
for(j=1;j<n+1;j++) //找出入度为0的节点
{
if(in[j]==0)
{
in[j]--;
ans[k++]=j;
for(c=1;c<n+1;c++) //删除与该节点关联的边
{
if(ma[j][c]==1)
in[c]--;
}
break;
}
}
}
}
int main()
{
int i,x,y;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(ma,0,sizeof(ma));
memset(in,0,sizeof(in));
memset(ans,0,sizeof(ans));
for(i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
if(ma[x][y]==0) //判重边,这里很重要
{
ma[x][y]=1;
in[y]++; //入度
}
}
topsort();
printf("%d",ans[0]);
for(i=1;i<n;i++)
printf(" %d",ans[i]);
printf("\n");
}
return 0;
}
节约内存,数据多的时候使用。
抄的模板,有好多地方不知道是怎么回事,但是会用就好
优先队列: 优化
优先队列怎么声明不知道ORZ
struct cmp
{
bool operator()(const int &a,const int &b)const
{
return a>b;
}
};
void topsort()
{
priority_queue<int,vector<int>,cmp>q;
int s=0;
for(int i=1;i<=n;i++)
{
if(in[i]==0)
q.push(i);
}
while(!q.empty())
{
int now=q.top(); //弹出的是入度为0的并且更小的那个数字
q.pop();
a[s++]=now; //存入数组
int l=v[now].size();
for(int i=0;i<l;i++)
{
int k=v[now][i];
in[k]--;
if(in[k]==0)
q.push(k);
}
}
}
#include<stdio.h>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;
vector<int>v[505];
int in[505],a[505];
int n,m;
struct cmp
{
bool operator()(const int &a,const int &b)const
{
return a>b;
}
};
void topsort()
{
priority_queue<int,vector<int>,cmp>q;
int s=0;
for(int i=1;i<=n;i++)
{
if(in[i]==0)
q.push(i);
}
while(!q.empty())
{
int now=q.top();
q.pop();
a[s++]=now;
int l=v[now].size();
for(int i=0;i<l;i++)
{
int k=v[now][i];
in[k]--;
if(in[k]==0)
q.push(k);
}
}
printf("%d",a[0]);
for(int i=1;i<n;i++)
printf(" %d",a[i]);
printf("\n");
}
int main()
{
int i,x,y,sum;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(in,0,sizeof(in));
memset(a,0,sizeof(a));
for(i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
v[x].push_back(y);
in[y]++;
}
topsort();
for(i=1;i<=n;i++)
v[i].clear();
}
return 0;
}