zoukankan      html  css  js  c++  java
  • hdu1532 用BFS求拓扑排序

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

    题目给出一些点对之间的先后顺序,要求给出一个字典序最小的拓扑排列。对于拓扑排序的问题,我们有DFS和BFS都能够解决,但是问题是DFS只能处理上一层结点和下一层结点相对于根节点之间的距离,也就是说深度就是他们之间的先后顺序,对于同一层的,是没有先后顺序的,但是BFS可以处理同一层之间的先后关系,所以我们考虑用BFS进行遍历,并且将原始BFS求拓扑排序中的队列变成优先队列。这样我们就能在每一层中优先选择字典序小的结点先输出。

    代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef unsigned int ui;
     4 typedef long long ll;
     5 typedef unsigned long long ull;
     6 #define pf printf
     7 #define mem(a,b) memset(a,b,sizeof(a))
     8 #define prime1 1e9+7
     9 #define prime2 1e9+9
    10 #define pi 3.14159265
    11 #define lson l,mid,rt<<1
    12 #define rson mid+1,r,rt<<1|1
    13 #define scand(x) scanf("%llf",&x) 
    14 #define f(i,a,b) for(int i=a;i<=b;i++)
    15 #define scan(a) scanf("%d",&a)
    16 #define mp(a,b) make_pair((a),(b))
    17 #define P pair<int,int>
    18 #define dbg(args) cout<<#args<<":"<<args<<endl;
    19 #define inf 0x3f3f3f3f
    20 const int maxn=505;
    21 int n,m,t;
    22 inline int read(){
    23     int ans=0,w=1;
    24     char ch=getchar();
    25     while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
    26     while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
    27     return ans*w;
    28 }
    29 struct node{
    30     int u,v;
    31 }p[maxn];
    32 int e;
    33 int vis[maxn][maxn],head[maxn],nxt[maxn],in[maxn],num[maxn];//in表示入度 
    34 void init()
    35 {
    36     e=0;
    37     mem(vis,0);mem(head,-1);mem(nxt,-1);mem(in,0);
    38     mem(num,0);//排名信息置零 
    39  } 
    40 void addedge(int u,int v)
    41 {
    42     p[e].u=u;
    43     p[e].v=v;
    44     nxt[e]=head[u];
    45     head[u]=e++;
    46 }
    47 void topsort()
    48 {
    49     priority_queue<int,vector<int> ,greater<int> > q;//最小堆 
    50     f(i,1,n)
    51     {
    52         if(in[i]==0)q.push(i);//将入度为零的点按照字典序排在优先队列中 
    53     }
    54     int t=0,id;//用BFS对付topsort时从队列中出来的点的顺序实际上就是topsort完成之后应该有的排序 
    55     while(!q.empty())
    56     {
    57         num[t++]=id=q.top();
    58         q.pop();
    59         for(int i=head[id];~i;i=nxt[i])//扫描从这一点出发的所有的边 
    60         {
    61             in[p[i].v]--;//所到的点的入度减一
    62             if(in[p[i].v]==0)q.push(p[i].v);//将入度为0的点归入优先队列 
    63         }
    64      }
    65     //将所有的点都扫描过之后,由于一定存在拓扑序,所以直接输出结果
    66      pf("%d",num[0]);
    67      f(i,1,n-1)pf(" %d",num[i]);
    68      pf("
    "); 
    69 }
    70 int main()
    71 {
    72     //freopen("input.txt","r",stdin);
    73     //freopen("output.txt","w",stdout);
    74     std::ios::sync_with_stdio(false);
    75     while(scanf("%d%d",&n,&m)!=EOF)
    76     {
    77             init();
    78             int a,b;
    79             f(i,1,m)
    80             {
    81                 a=read(),b=read();
    82                 if(!vis[a][b])//保证两条边之间的只有一条有向边,否则出入度就会发生变化,导致错误 
    83                 {
    84                     addedge(a,b);
    85                     vis[a][b]=1;
    86                     in[b]++; 
    87                 }
    88              }
    89              topsort(); 
    90     }
    91 
    92 } 
  • 相关阅读:
    共享内存
    用system v消息队列实现回射客户/服务器程序
    消息队列
    在一个递增数组的rotate变换中找target
    栈(Stack)和队列(Queue)是两种操作受限的线性表。
    new与malloc的10点区别(转)
    如何在Ubuntu中安装安全更新
    如何使用Mod_Security和Mod_evasive模块保护Apache 提升DDOS防御力
    如何在Nginx上修复502 Bad Gateway错误
    如何在Ubuntu 20.04上使用Apache和mod_wsgi运行Python脚本?
  • 原文地址:https://www.cnblogs.com/randy-lo/p/12577618.html
Copyright © 2011-2022 走看看