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;
    }
  • 相关阅读:
    EntityFramework系列:MySql的RowVersion
    EntityFramework系列:SQLite.CodeFirst自动生成数据库
    怎么回事呢?
    为蛇么不现实
    发布到个人主页
    作别
    budao 首页
    中午吃饱了
    作业写好了吗?
    分类
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3264813.html
Copyright © 2011-2022 走看看