题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285

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

代码例如以下:

一、(直接法)

#include <cstdio>
#include <cstring>
#define MAXN 517
int G[MAXN][MAXN];//路径
int in_degree[MAXN];//入度
int ans[MAXN];
int n, m, x, y;
int i, j; void toposort()
{
for(i = 1; i <= n; i++)
{
for(j = 1; j <= n; j++)
{
if(G[i][j])
{
in_degree[j]++;
}
}
}
for(i = 1; i <= n; i++)//从最小的開始寻找。
{//这样保证了有多个答案时序号小的先输出
int k = 1;
while(in_degree[k] != 0)//寻找入度为零的点
k++;
ans[i] = k;
in_degree[k] = -1;
//更新为-1。后边检測不受影响,相当于删除节点
for(int j = 1; j <= n; j++)
{
if(G[k][j])
in_degree[j]--;//相关联的入度减1
}
}
} void init()
{
memset(in_degree,0,sizeof(in_degree));
memset(ans,0,sizeof(ans));
memset(G,0,sizeof(G));
} int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
for(i = 0; i < m; i++)
{
scanf("%d%d",&x,&y);
G[x][y] = 1;
}
toposort();
for(i = 1; i < n; i++)
printf("%d ",ans[i]);
printf("%d\n",ans[n]);
}
return 0;
}

二、拓扑排序+优先队列:

#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
bool map[517][517];
int in[517];
priority_queue<int,vector<int>,greater<int> > q;
void topo(int n)
{
for(int i=1;i<=n;i++)
{
if(in[i]==0)
q.push(i);
}
int c=1;
while(!q.empty())
{
int v=q.top();
q.pop();
if(c!=n)
{
cout<<v<<" ";
c++;
}
else
cout<<v<<endl;
for(int i=1;i<=n;i++)
{
if(!map[v][i])
continue;
in[i]--;
if(!in[i])
q.push(i); }
}
}
int main()
{
int n,m,i,j;
while(cin>>n>>m)
{
int k=0;
memset(map,0,sizeof map);
memset(in,0,sizeof in);
while(m--)
{
cin>>i>>j;
if(map[i][j])
continue;
map[i][j]=1;
in[j]++;
}
topo(n);
}
}

三、邻接表+拓扑排序:

①:数组式邻接表:

代码例如以下:

#include <iostream>
using namespace std;
int ind[517]; // indegree入度个数
int adj[250017]; //adjacency list邻接表位置值
int adj_next[250017];//邻接表下一指针
int tail[517]; //邻接表尾 int main()
{
int n,m,i,j,a,b;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i = 0; i <= n; i++)
{
tail[i] = -1;
adj[i] = -1;
adj_next[i] = -1;
ind[i] = 0;
}
for(i = 0; i < m; ++i)
{
scanf("%d%d",&a,&b);
int x = tail[a],flag = 0;
while(x != -1) //推断是否重边
{
if(adj[x] == b)
{
flag = 1;
break;
}
x = adj_next[x];
}
if(!flag)//关联a的邻接表
{
adj[i] = b;
adj_next[i] = tail[a];
tail[a] = i;
ind[b] ++;
}
}
for(i = 1;i <= n; i++)//找n次
{
for(j = 1;j <= n;j++)//遍历
{
if(ind[j] == 0)//当入度为0时,说明靠前
{
ind[j] = -1;//在下次寻找入度为0时跳过
if(i == 1)
printf("%d",j);
else
printf(" %d",j);
for(int k = tail[j]; k != -1; k = adj_next[k])//邻接位置入度减一
{
ind[adj[k]]--;
}
break;
}
}
}
printf("\n");
}
return 0;
}

②:结构体(链表)式邻接表:

代码例如以下:

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<cstdio>
#include<queue>
#include<bitset>
using namespace std;
#define maxn 517 struct node
{
int num;
node *next;
}; node map[maxn];
int d[maxn], n; void Insert(int a, int b);
void Free();
void Topsort(); int main()
{
int m; while(cin >> n >> m)
{
int i, a, b; memset(d, 0, sizeof(d)); for(i=0; i<m; i++)
{
cin >> a >> b;
Insert(a, b);
d[b]++;
} Topsort();
Free();
} return 0;
}
void Insert(int a, int b)
{
node *newnode; newnode = (node *)malloc(sizeof(node));
newnode->num = b;
newnode->next = map[a].next;
map[a].next = newnode;
}
void Free()
{
node *cur, *old; for(int i=1; i<=n; i++)
{
cur = map[i].next;
while(cur)
{
old = cur;
cur = cur->next;
free(old);
}
map[i].next = NULL;
}
}
void Topsort()
{
priority_queue<int, vector<int>, greater<int> > que;
int nx, i;
int q[maxn]={0}, k=0;
node *cur; for(i=1; i<=n; i++)
{
if(d[i] == 0)
que.push(i);
} while(que.size())
{
nx = que.top(), que.pop();
q[k++] = nx; cur = map[nx].next;
while(cur)
{
nx = cur->num;
d[nx] -= 1; if(d[nx] == 0)
que.push(nx);
cur = cur->next;
}
} cout << q[0];
for(i=1; i<k; i++)
cout <<" "<< q[i];
cout <<endl;
}

hdu1285 确定比赛名次(拓扑排序多种方法)的更多相关文章

  1. hdu1285 确定比赛名次(拓扑排序)

    有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道 ...

  2. hdu1285确定比赛名次(拓扑排序+优先队列)

    传送门 第一道拓扑排序题 每次删除入度为0的点,并输出 这题要求队名小的排前面,所以要用到重载的优先队列 #include<bits/stdc++.h> using namespace s ...

  3. HDU.1285 确定比赛名次 (拓扑排序 TopSort)

    HDU.1285 确定比赛名次 (拓扑排序 TopSort) 题意分析 裸的拓扑排序 详解请移步 算法学习 拓扑排序(TopSort) 只不过这道的额外要求是,输出字典序最小的那组解.那么解决方案就是 ...

  4. ACM: HDU 1285 确定比赛名次 - 拓扑排序

     HDU 1285 确定比赛名次 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u De ...

  5. hdu 1285 确定比赛名次 拓扑排序

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛 ...

  6. HDOJ 1285 确定比赛名次(拓扑排序)

    Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委 ...

  7. HDU1285-确定比赛名次-拓扑排序板子题

    有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道 ...

  8. HDU 1285 确定比赛名次 拓扑排序模板题

    http://acm.hdu.edu.cn/showproblem.php?pid=1285 #include <cstdio> #include <cstdlib> #inc ...

  9. 图论--拓扑排序--HDU-1285确定比赛名次

    Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委 ...

随机推荐

  1. 零基础学python-3.5 内存管理

    * 变量无需事先声明 * 变量无需指定类型 * 程序猿不用关系内存管理 * 变量名会被回收 * del能够直接释放资源 1.python使用的是引用调用,而不是值调用,他使用的回收算法是引用计数算法, ...

  2. 【云计算】使用docker搭建nfs实现容器间共享文件

    首先介绍下今天的两个主角:nfs和docker nfs 是什么 NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TC ...

  3. RUP(Rational Unified Process),统一软件开发过程

    RUP(Rational Unified Process),统一软件开发过程 https://baike.baidu.com/item/RUP/8924595?fr=aladdin RUP最重要的它有 ...

  4. T-SQL 之 公用表表达式(CTE)

    在编写T-SQL代码时,往往需要临时存储某些结果集.在CTE之前常用的两种临时存储结果集为:临时表和表变量.除此之外,还可以使用公用表表达式的方法. 公用表表达式(Common Table Expre ...

  5. request.getHeader不区分大小写

    <!--查看输出信息--><% System.out.println("Header...."); Enumeration<String> e = r ...

  6. javascript forEach方法与jQuery each区别

    1.forEach方法 语法: array.forEach(function(currentValue, index, arr), thisValue) 参数: 示例: <!DOCTYPE ht ...

  7. linux sheel重复执行上条命令

    Linux系统下Shell重复执行上条命令的 4 种方法: 1.使用上方向键,并回车执行. 2.按 !! 并回车执行. 3.输入 !-1 并回车执行. 4.按 Ctrl+P 并回车执行.

  8. openerp创建动态视图-fields_view_get

    openerp的视图结构是以XML的格式存放于ir.ui.view表中,属于静态格式,设计之后就固定, 但可以通过在model中重写fields_view_get函数,在视图加载时修改arch属性,动 ...

  9. UML学习(二)- 用例图

    UML用例图      用例图主要用来图示化系统的主事件流程,它主要用来描述客户的需求,即用户希望系统具备的完成一定功能的动作,通俗地理解用例就是软件的功能模块,所以是设计系统分析阶段的起点,设计人员 ...

  10. knockoutjs -- if 绑定

    参考:http://knockoutjs.com/documentation/if-binding.html If 绑定用来控制一部分html标签是否生成在DOM树中(html标签有data-bind ...