Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 38468 Accepted Submission(s): 14932 Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。
Input 输入有若干组,每组中的第一行为二个数N(1<=N<=500),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
Author SmallBeer(CML)
Source
Recommend lcy | We have carefully selected several similar problems for you: 1233 2544 1811 2066 1548 |
题目大意:给你N个点,M条边(有向边也就是先后顺序),其中点是不能为0的,对其进行拓扑排序,问你字典序最小的路径
思路:字典序最小的,自然就想到了优先队列,较小值在队列顶部的那种,
其实和一般的拓扑题目差不多,只是号码,也就是编号是不能为0的,所以一开始找入度为0的点的时候就不要找0号了,
就这点吧,一开始输出该有的节点发现还有个0,。。。贼尴尬
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<vector>
#define maxn 550
using namespace std;
int n,m;
vector<int >G[maxn];
int in[maxn];
void topo()
{
priority_queue<int,vector<int>,greater<int> > Q;//小顶锥的优先队列
int ans[maxn],cnt=0;
for(int i=1;i<=n;i++) //一开始的出错点
if(in[i]==0) Q.push(i);
while(!Q.empty())
{
int u=Q.top();
Q.pop();
ans[cnt++]=u;
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(--in[v]==0)
{
Q.push(v);
}
}
}
printf("%d",ans[0]);
for(int i=1;i<n;i++)
printf(" %d",ans[i]);
puts("");
}
int main()
{
while(scanf("%d%d",&n,&m)==2)
{
memset(in,0,sizeof(in));
for(int i=0;i<=n;i++) G[i].clear();
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
in[v]++;
}
topo();
}
return 0;
}