• POJ2135 最小费用最大流模板题


    练练最小费用最大流

    此外此题也是一经典图论题

    题意:找出两条从s到t的不同的路径,距离最短。

      要注意:这里是无向边,要变成两条有向边

    #include <cstdio>
    #include <cstring>
    #define MAXN 1005
    #define MAXM 10005
    #define INF 0x3f3f3f3f
    
    struct Edge
    {
        int y,c,w,ne;//c容量 w费用
    }e[MAXM*4];
    
    int n,m,x,y,w;
    int s,t,Maxflow,Mincost;
    int all,be[MAXN];
    int q[MAXM*4],dis[MAXN],pre[MAXN];//pre存的是当前点的前边
    bool vis[MAXN];
    
    void add(int x, int y, int c, int cost)
    {
        e[all].y=y;e[all].c=c;e[all].w=cost;
        e[all].ne=be[x];
        be[x]=all++;
        e[all].y=x;e[all].c=0;e[all].w=-cost;//反向边费用取负
        e[all].ne=be[y];
        be[y]=all++;
    }
    
    void init()
    {
        all=0;
        memset(be,-1,sizeof(be));
    }
    bool spfa(int s, int t)
    {
        for(int i=0; i<MAXN; i++)
        {
            dis[i]=INF;
            vis[i]=0;
            pre[i]=-1;
        }
        dis[s]=0;
        vis[s]=1;
        int head=0,tail=0;
        q[++tail]=s;
        while(head<tail)
        {
            int u=q[++head];
            vis[u]=0;
            for(int i=be[u]; i!=-1; i=e[i].ne)
            {
                int v=e[i].y;
                if(e[i].c>0 && dis[v]>dis[u]+e[i].w)
                {
                    dis[v]=dis[u]+e[i].w;
                    pre[v]=i;
                    if(!vis[v])
                    {
                        vis[v]=1;
                        q[++tail]=v;
                    }
                }
            }
        }
        if(pre[t]==-1) return 0;
        return 1;
    }
    void MincostMaxflow(int s, int t)
    {
        Maxflow=0;
        Mincost=0;
        while(spfa(s,t))
        {
            int minc=INF;
            for(int i=pre[t]; i!=-1; i=pre[e[i^1].y])
                if(minc>e[i].c) minc=e[i].c;
            for(int i=pre[t]; i!=-1; i=pre[e[i^1].y])
            {
                e[i].c-=minc;
                e[i^1].c+=minc;
                Mincost+=e[i].w*minc;
            }
            Maxflow+=minc;
        }
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        init();
        s=n+1;
        t=n+2;
        for(int i=0; i<m; i++)
        {
            scanf("%d%d%d",&x,&y,&w);
            add(x,y,1,w);
            add(y,x,1,w);
        }
        add(s,1,2,0);
        add(n,t,2,0);
        MincostMaxflow(s,t);
        printf("%d
    ",Mincost);
        return 0;
    }
    View Code
  • 相关阅读:
    2019年1月26日训练日记
    2019年1月25日训练日记
    2019年1月24日训练日记
    2019年1月23日训练日记
    2019年1月22日训练日记
    2019年1月21日训练日记
    2019年1月20日训练日记
    2019年1月19日训练日记
    2019年1月18日训练日记
    C语言学习小结
  • 原文地址:https://www.cnblogs.com/Mathics/p/3910445.html
Copyright © 2020-2023  润新知