zoukankan      html  css  js  c++  java
  • hdu 2647 Reward

    拓扑排序入门题,可以用STL来做,这份代码中没有用

    对于给出的图判断是否为有向无环图(dag),若不是,输出-1

    其实是按层来处理拓扑序列,算法是先找出入度为0的点,然后删除所有以这些顶点为弧尾的弧,使弧头的入度减1,然后再看下一轮的顶点中那些顶点入度为0,然后依此类推,直到所有点的入度都为0,如果最后结束的时候所有点入度为0,那么是一个dag,否则不是,输出-1,这个过程可以用队列来实现,这个代码里面没有这样做,而是每一层都重新扫描一遍,找出入度为0的顶点(之前已经纳入拓扑序列的顶点就用vis[i]=1来标记),应该用队列实现的话时间会更好

    另外其中是要构建邻接表的,用数组来构建,当然可以直接用STL的vector来实现,队列也可以用STL的queue来实现,这份代码中都没有这样做

    另外注意一点,输入中a b  有向边是b->a , 不要搞反了 

    #include <stdio.h>
    #include <string.h>
    #define MAXN 10010
    #define MAXM 20010
    int n,m;
    int first[MAXN],in[MAXN];
    int u[MAXM],v[MAXM],next[MAXM];
    bool vis[MAXN];
    
    void input()
    {
        int i,a,b,f;
        memset(first,-1,sizeof(first));
        memset(in,0,sizeof(in));
        for(f=1,i=0; i<m; i++)
        {
            scanf("%d%d",&a,&b);
            u[i]=b; v[i]=a;
            in[v[i]]++;
            next[i]=first[u[i]];
            first[u[i]]=i;
        }
    }
    
    int topsort()
    {
        int sum;
        int temp[MAXN];
        int i,j,k,c,t;
        memset(vis,0,sizeof(vis));
    c=0;  sum=0; j=0;  
    //j表示的是层数,第一层是0,所以工资为888,依次是889.890
    //c表示已经有多少个点纳入拓扑序列,c=n则是dag
    //sum是最后的答案
    while(1)
        {
            k=0;
            for(i=1; i<=n; i++)  //对应n个顶点
                if(!vis[i] && in[i]==0)
                {
                    vis[i]=1;  c++;  sum+=(888+j);
                    temp[k++]=i;  //记录下当前这一轮找到的入度为0的顶点
                }
            if(c>=n)  return sum;
            if(!k)    return -1; 
        //如果在这次构建结束后,扫描所有顶点都找不到入度为0那说明存在环
            for(i=0; i<k; i++)  
    //对应temp数组,这一轮找到的入度为0的顶点,要遍历它的邻接表,使对应的弧头入度减1
            {
                t=temp[i];  //记录弧尾顶点标号
                t=first[t];  //记录这个顶点的第一条弧的编号
                while(t!=-1)  
                {
                    in[v[t]]--;
                    t=next[t];
                }
            }
    
            j++;
        }
    }
    
    int main()
    {
        int ans;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            input();
            printf("%d\n",ans=topsort());
        }
        return 0;
    }
  • 相关阅读:
    数据持久化编程学习总结
    Boost Replaceable by C++11 language features or libraries
    【敬业福bug】支付宝五福卡敬业福太难求 被炒至200元
    由文字生成path后制作写字的动画
    CSS经典布局之弹性布局
    HDU2082 找单词 【母函数】
    HDOJ 题目2475 Box(link cut tree去点找祖先)
    DELPHI中MDI子窗口的关闭 和打开
    sql语句中日期相减的操作
    Delphi编码规范
  • 原文地址:https://www.cnblogs.com/scau20110726/p/2728232.html
Copyright © 2011-2022 走看看