hdu1285 拓扑排序+邻接矩阵(邻接表)

来源:互联网 发布:去小公司写php怎么样 编辑:程序博客网 时间:2024/06/11 05:01

给出胜负关系,要求确定名次

本来就是冲着学写邻接表什么的去的。。

拓扑排序呢,就是确定次序的东西啦,一般似乎用入度表达,前一个点访问过了,就把它指过的点的入度减掉

第一个是邻接矩阵的,已经详细注解啦,第二份留下来观摩大神的邻接表,附上~


邻接矩阵:


#include <stdio.h>#include <string.h>using namespace std;const int MAXN=505;int map[MAXN][MAXN],n,m,a,b,in[MAXN],ans[MAXN];void topo()//本来写了三层套着的循环。。。看这里http://blog.csdn.net/swm8023/article/details/6770700{int cnt=1,j;memset(ans,0,sizeof ans);while(true){for(j=1;j<=n;j++)            if(in[j]==0)//找到入度为0的j                break;if(j==n+1)//最后j还加了一下,返回的            return;in[j]=-1;//这个点下次不会再进来了ans[cnt++]=j;//把j存进去for(int k=1;k<=n;k++)            if(map[j][k]==1)//因为j已经存进去了,所以那些可以被j打败的,入度-1                in[k]--;}}int main(){while(scanf("%d%d",&n,&m)!=EOF)    {memset(map,0,sizeof map);memset(in,0,sizeof in);while(m--)        {scanf("%d%d",&a,&b);if(map[a][b]==0)//可能有重边,以防in[]重复计算            {                map[a][b]=1;                in[b]++;            }}topo();//拓扑排序for(int i=1;i<n;i++)//顺序都存在ans里~            printf("%d ",ans[i]);printf("%d\n",ans[n]);}return 0;}




邻接表:

#include <iostream>using namespace std;int ind[505];       // indegree入度个数int adj[250010];    //adjacency list邻接表位置值int adj_next[250010];//邻接表下一指针int tail[505];      //邻接表尾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++)        {            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;}


0 0