您的位置:首页 > 其它

HDU 1285 -- 确定比赛名次 (拓扑排序)

2015-01-14 15:09 183 查看
题目大意:有N个队伍比赛,给出M行输赢关系,要求输出一个排名,符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。

思路分析:利用小顶堆,直接进行拓扑排序就行。

代码实现:

邻接表:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int top,cnt,degree[510],out[510];
priority_queue<int,vector<int>,greater<int> > q;
struct Edge{
int v;
Edge *next;
}*head[510],e[250000];
void Addedge(int from,int to){
Edge *p=&e[top++];
p->v=to;
p->next=head[from];
head[from]=p;
}
void Tuopu(int n){
for(int i=1;i<=n;i++){
if(degree[i]==0)
q.push(i);
}
while(!q.empty()){
int a=q.top();
out[cnt++]=a;
q.pop();
for(Edge *p=head[a];p;p=p->next){
degree[p->v]--;
if(degree[p->v]==0)
q.push(p->v);
}
}
printf("%d",out[0]);
for(int i=1;i<cnt;i++)
printf(" %d",out[i]);
printf("\n");
}
int main(){
int n,m;
while(~scanf("%d%d",&n,&m)){
memset(head,0,sizeof(head));
memset(degree,0,sizeof(degree));
top=0,cnt=0;
for(int i=0;i<m;i++){
int a,b;
scanf("%d%d",&a,&b);
Addedge(a,b);
degree[b]++;
}
Tuopu(n);
}
return 0;
}


邻接矩阵:

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=510;
priority_queue<int,vector<int>,greater<int> >q;
int cnt,map[maxn][maxn],degree[510],out[510];
void Tuopu(int n){
for(int j=1;j<=n;j++){
if(degree[j]==0){
q.push(j);
}
}
while(!q.empty()){
int a=q.top();
q.pop();
out[cnt++]=a;
for(int i=1;i<=n;i++){
if(map[a][i]){
degree[i]--;
if(degree[i]==0)
q.push(i);
}

}
}
printf("%d",out[0]);
for(int i=1;i<cnt;i++)
printf(" %d",out[i]);
printf("\n");
}
int main(){
int n,m;
while(~scanf("%d%d",&n,&m)){
memset(map,0,sizeof(map));
memset(degree,0,sizeof(degree));
memset(out,0,sizeof(out));
cnt=0;
for(int i=0;i<m;i++){
int a,b;
scanf("%d%d",&a,&b);
if(!map[a][b])//实验了很多次,一定要先判断这组关系是不是已经存在了,如果存在,b的入度就不变,否则会WA
degree[b]++;
map[a][b]=1;
}
Tuopu(n);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: