确定比赛名次Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 41540 Accepted Submission(s): 15994 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
|
拓扑排序,
从前往后遍历所有入度为0的顶点,输出,然删除这个顶点和与之有关的边,重复这个步骤
#include<bits/stdc++.h>
#define M 505
using namespace std;
int in[M],n,m;
bool dir[M][M];
void toposort()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(!in[j])//如果入度为0
{
in[j]=-1;//删除这个顶点
cout<<j;
if(i!=n) cout<<' ';
else cout<<endl;
for(int k=1;k<=n;k++)//删除有关这个顶点的边
if(dir[j][k]) in[k]--;
break;
}
}
int main()
{
int x,y;
while(cin>>n>>m)
{
memset(in ,0,sizeof( in));
memset(dir,0,sizeof(dir));
while(m--)
{
cin>>x>>y;
if(!dir[x][y])//去重
{
dir[x][y]=1;
in[y]++;
}
}
toposort();
}
return 0;
}
#include<bits/stdc++.h>
#define M 505
using namespace std;
int in[M],n,m;
bool dir[M][M];
vector<int> V;
priority_queue<int,vector<int>,greater<int> > Q;
void toposort()
{
for(int i=1;i<=n;i++)
if(!in[i]) Q.push(i);
while(!Q.empty())
{
int x=Q.top(); Q.pop();
V.push_back(x);
for(int i=1;i<=n;i++)
if(dir[x][i])
{
in[i]--;
if(!in[i])
Q.push(i);
}
}
}
int main()
{
int x,y;
while(cin>>n>>m)
{
memset(in ,0,sizeof( in));
memset(dir,0,sizeof(dir));
V.clear();
while(m--)
{
cin>>x>>y;
if(!dir[x][y])//去重
{
dir[x][y]=1;
in[y]++;
}
}
toposort();
for(int i=0;i<V.size()-1;i++)
cout<<V[i]<<' ';
cout<<V[V.size()-1]<<endl;
}
return 0;
}