zoukankan      html  css  js  c++  java
  • DAG的运用:拓扑排序(AOV),关键路径(AOE)与dp的关系

    dp在DAG中有两个运用,一个是固定终点和起点的最长路(最短路)

    其中最长路的算法就是关键路径(AOE)的算法。

    下面是代码

    #include<cstdio>
    #include<algorithm>
    #define maxn 2001
    using namespace std;
    int a[10],head[maxn],n,p,f[maxn],tp[maxn],de[maxn],ds[maxn];
    struct ss
    {
        int to,w,last;
    }x[maxn*1000];
    void add(int a,int b,int c)
    {
        x[++p].to=b;
        x[p].last=head[a];
        x[p].w=c;
        head[a]=p;
    }
    int dp(int a)
    {
        if(f[a]!=0) return f[a];
        if(!de[a]) return 0;
        int v=head[a],t=0;
        while(v)
        {
            if(dp(x[v].to)+x[v].w>t)
                {
                 t=dp(x[v].to)+x[v].w;
                 ds[a]=x[v].to;
                }
            v=x[v].last;
        }
        f[a]=t;
        return f[a];
    }
    void out(int a)
    {
        if(!a) return;
        out(ds[a]);
        printf("%d ",a);
    }
    int main()
    {
        scanf("%d",&n);
        int a1,a2,a3;
        while(scanf("%d%d%d",&a1,&a2,&a3)==3)
        {
            add(a2,a1,a3);
            de[a2]++;
        }
        int ans=0,ansv;
        for(int i=1;i<=n;i++)
            if(dp(i)>ans)
             {
              ans=dp(i);
              ansv=i;
             }
        printf("%d
    ",ans);    
        out(ansv);
        return 0;
    }
     

    关于拓扑排序(AOV)有两个算法,一个是dfs,运用搜索树的性质,其一个点的子节点输出完后,再输出父节点。

    还有就是广搜算法

    下面给出代码

    dfs

    #include<cstdio>
    #define N 2000+10
    using namespace std;
    int head[N],num;
    struct edge{
        int next,to;
    }e[N*(N-1)];
    int dfn[N][2],degree[N],ok=1,index,tot=0,topu[N];
    void add(int from,int to)
    {
        e[++num].next=head[from];
        e[num].to=to;
        head[from]=num;
    }
    void dfs(int u)
    {
        if(!ok)return;
        dfn[u][0]=++index;
        for(int i=head[u];i;i=e[i].next)
        {
            int v=e[i].to;
            if(dfn[v][0]&&!dfn[v][1]){ok=0;return;}
            else if(!dfn[v][0]){
                dfs(v);
            }
        }
        dfn[u][1]=++index;
        topu[tot--]=u;
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        int x,y;
        while(scanf("%d%d",&x,&y)==2){add(x,y);degree[y]++;}
        int flag=0;
        for(int i=1;i<=n;i++)
        {
            if(degree[i]==0){x=i,flag=1;}
        }
        if(!flag){printf("NO");return 0;}
        tot=n;
        for(int i=1;i<=n;i++)
        {
            if(!ok)break;
            if(!dfn[i][0]/*&&degree[i]==0*/)dfs(i);
        }
        if(ok==0){printf("NO");return 0;}
        for(int i=1;i<=n;i++)printf("%d ",topu[i]);
        return 0;
    }

    bfs

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,a,b,head[2001],num,z[2001],top,cl,op,deg[2001];
    struct ss
    {
        int last,to;
    }e[2000000];
    void add(int a,int b)
    {
        e[++num].last=head[a];
        e[num].to=b;
        head[a]=num;
    }
    void bfs()
    {
        cl=1;
        while(cl<=top)
        {
            int m=z[cl],t=head[m];
            while(t)
            {
                deg[e[t].to]-=1;
                if(deg[e[t].to]==0)
                    z[++top]=e[t].to;
                t=e[t].last;
            }
            cl+=1;
        }
    }
    int main()
    {
        scanf("%d",&n);
        while(scanf("%d%d",&a,&b)==2)
        {
            add(a,b);
            deg[b]++;
        }
        for(int i=1;i<=n;i++)
        if(deg[i]==0)z[++top]=i;
        bfs();
        if(top<n)printf("NO");
        else
        for(int i=1;i<=top;i++)
        printf("%d ",z[i]);
        return 0;
    }
  • 相关阅读:
    PHP面试题遇到的几个坑。...面壁ing
    Java基础- super 和 this 解析
    openStack use
    ceph伦理概念
    openstack core components use 总结
    current imporant Posts
    openNebula rgister img instance vms error collections
    openStack images概念及维护
    Error copying image in the datastore: Not allowed to copy image file
    OpenNebula openldap集成
  • 原文地址:https://www.cnblogs.com/star-eternal/p/7607666.html
Copyright © 2011-2022 走看看