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;
    }
  • 相关阅读:
    Eclipse IDE中Android项目打红叉的解决方法
    控件:PopupWindow 弹出窗口(基本操作)
    控件:AnalogClock与DigitalClock 时钟组件
    四大组件之一 BroadcastReceiver (拦截短信并屏蔽系统的Notification .)
    四大组件之一 文件存储_文本文件
    控件:Chronometer 计时器(定时震动)
    计算页面执行时间的两种方法
    URL解析的几种模式以及拟静态重定向问题
    SSH 文件上传错误:encountered 1 errors during the transfer终极解决方法:
    php过滤提交信息防注入
  • 原文地址:https://www.cnblogs.com/scau20110726/p/2728232.html
Copyright © 2011-2022 走看看