zoukankan      html  css  js  c++  java
  • hdu 4411 最小费用流

    思路:主要就是要把一个每个城市拆为两个点,建一条容量为1,费用为-inf的边,保证每个城市都会被遍历。

    /*最小费用最大流*/
    #include<iostream>
    #include<cstring>
    #include<cstring>
    #include<cmath>
    #include<cstdio>
    using namespace std;
    const int Maxn = 1010;
    const int inf = 1000010;
    struct Edge{
        int v;
        int val;
        int cost;
        int next;
    }edge[Maxn*100];
    int head[Maxn],n,g[Maxn][Maxn],m,k;
    int e;
    int pre[Maxn], pos[Maxn];
    int dis[Maxn], que[Maxn*100];
    bool vis[Maxn];
    void add(int u, int v, int val, int cost)
    {
        edge[e].v = v;
        edge[e].val = val;
        edge[e].cost = cost;
        edge[e].next = head[u];
        head[u] = e++;
        edge[e].v = u;
        edge[e].val = 0;
        edge[e].cost = -cost;
        edge[e].next = head[v];
        head[v] = e++;
    }
    void init()
    {
        memset(head,-1,sizeof(head));
        for(int i=0;i<Maxn;i++)
            for(int j=0;j<Maxn;j++)
            g[i][j]=inf;
        e=0;
    }
    bool spfa(int s, int t)
    {
        int i;
        memset(pre, -1, sizeof(pre));
        memset(vis, 0, sizeof(vis));
        int Head, tail;
        Head = tail = 0;
        for(i = 0; i < Maxn; i++)
            dis[i] = inf;
        que[tail++] = s;
        pre[s] = s;
        dis[s] = 0;
        vis[s] = 1;
        while(Head != tail)
        {
            int now = que[Head++];
            vis[now] = 0;
            for(i=head[now]; i != -1; i = edge[i].next)
            {
                int adj = edge[i].v;
                //cout<<now<<" "<<adj<<" "<<dis[now]<<" "<<edge[i].cost<<" "<<dis[adj]<<" "<<edge[i].val<<endl;
                if(edge[i].val > 0 && dis[now] + edge[i].cost < dis[adj])
                {
                    dis[adj] = dis[now] + edge[i].cost;
                    pre[adj] = now;
                    pos[adj] = i;
                    if(!vis[adj])
                    {
                        vis[adj] = 1;
                        que[tail++] = adj;
                    }
                }
            }
        }
        return pre[t] != -1;
    }
    int MinCostFlow(int s, int t, int flow)
    {
        int i;
        int cost = 0;
        flow = 0;
        while(spfa(s, t))
        {
            int f = inf;
            for(i = t; i != s; i = pre[i])
            if (edge[pos[i]].val < f)
                f = edge[pos[i]].val;
                flow += f;
                cost += dis[t] * f;
                for(i = t; i != s; i = pre[i])
                {
                    edge[pos[i]].val -= f;
                    edge[pos[i] ^ 1].val += f;
                }
           // cout<<cost<<endl;
        }
        return cost;
        // flow是最大流值
    }
    void floyd()
    {
        int i,j,k;
        for(k=0;k<=n;k++)
            for(i=0;i<=n;i++)
            for(j=0;j<=n;j++)
            {
                if(g[k][j]==inf) continue;
               g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
            }
    }
    void build(int lim)
    {
        memset(head,-1,sizeof(head));
        e=0;
        int ss = 0;
        int s = 2*n+1;
        int t = 2*n+2;
        add(s,ss,lim,0);
        for(int i=1;i<=n;i++)
        {
            if(g[0][i] < inf)
            {
                add(ss,i,1,g[0][i]);
                add(i+n,t,1,g[i][0]);
            }
            add(i,i+n,1,-inf);
            for(int j=i+1;j<=n;j++)
            {
                if(g[i][j] < inf)
                {
                add(i+n,j,1,g[i][j]);
                }
            }
        }
        add(ss,t,k,0);
        return;
    }
    int solve()
    {
        int i,j;
        int ans;
        ans=inf;
        build(k);
        ans=min(ans,MinCostFlow(n+n+1,n+n+2,0)+n*inf);
        return ans;
    }
    int main()
    {
        int i,j,u,v,c;
        while(scanf("%d%d%d",&n,&m,&k)!=EOF,n||m||k)
        {
            init();
            for(i=1;i<=m;i++)
            {
                scanf("%d%d%d",&u,&v,&c);
                if(g[u][v]>c)
                g[u][v]=g[v][u]=c;
            }
            floyd();
            printf("%d
    ",solve());
        }
        return 0;
    }
  • 相关阅读:
    Zabbix5 Frame 嵌套
    Zabbix5 对接 SAML 协议 SSO
    CentOS7 安装 Nexus
    CentOS7 安装 SonarQube
    GitLab 后台修改用户密码
    GitLab 查看版本号
    GitLab Admin Area 500 Error
    Linux 安装 PostgreSQL
    Liger ui grid 参数
    vue.js 是一个怪东西
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3264813.html
Copyright © 2011-2022 走看看