zoukankan      html  css  js  c++  java
  • 1753: 分配问题 二分最佳匹配/最小费用流与最大费用流

    有n件工作要分配给n个人做。第i 个人做第j 件工作产生的效益为Cij 。试设计一个将 n件工作分配给n个人做的分配方案,使产生的总效益最大。

    编程任务: 对于给定的n件工作和n个人,计算最优分配方案和最差分配方案。

    把所有人看做二分图中顶点Xi,所有工作看做二分图中顶点Yi,建立附加源S汇T。

    1、从S向每个Xi连一条容量为1,费用为0的有向边。
    2、从每个Yi向T连一条容量为1,费用为0的有向边。
    3、从每个Xi向每个Yj连接一条容量为无穷大,费用为Cij的有向边。

    求最小费用最大流,最小费用流值就是最少运费,求最大费用最大流,最大费用流值就是最多运费。

    /* 
     * Problem: 线性规划与网络流24题 #18 分配问题
     * Author: Guo Jiabao
     * Time: 2009.6.29 18:29
     * State: Solved
     * Memo: 费用流
    */
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    using namespace std;
    const int MAXN=102*2,MAXM=MAXN*MAXN*2,INF=~0U>>1;
    struct Queue
    {
        int Q[MAXN],head,tail,size;
        bool inq[MAXN];
        void init()
        {
            memset(inq,0,sizeof(inq));
            head = size =0; tail = -1;
        }
        void ins(int p)
        {
            size++;
            if (++tail == MAXN) tail = 0;
            Q[tail] = p;
            inq[p]=true;
        }
        int pop()
        {
            size--;
            int p=Q[head];
            if (++head == MAXN) head = 0;
            inq[p]=false;
            return p;
        }
    }Q;
    struct edge
    {
        edge *next,*op;
        int t,c,v;
    }*V[MAXN],ES[MAXM],*fe[MAXN];
    int N,S,T,EC,Ans,Costflow;
    int Sc[MAXN][MAXN],dist[MAXN],ft[MAXN];
    inline void addedge(int a,int b,int c,int v)
    {
        ES[++EC].next = V[a]; V[a]=ES+EC; V[a]->t=b; V[a]->c=c; V[a]->v=v;
        ES[++EC].next = V[b]; V[b]=ES+EC; V[b]->t=a; V[b]->c=0; V[b]->v=-v;
        V[a]->op = V[b]; V[b]->op = V[a];
    }
    void init()
    {
        int i,j;
        freopen("job.in","r",stdin);
        freopen("job.out","w",stdout);
        scanf("%d",&N);
        S=0; T=N+N+1;
        for (i=1;i<=N;i++)
            for (j=1;j<=N;j++)
                scanf("%d",&Sc[i][j]);
    }
    bool SPFA()
    {
        int i,j;
        for (i=S;i<=T;i++)
            dist[i]=INF;
        dist[S]=0;
        Q.ins(S);
        while (Q.size)
        {
            i=Q.pop();
            for (edge *e=V[i];e;e=e->next)
            {
                j=e->t;
                if (e->c && dist[i] + e->v < dist[j])
                {
                    dist[j] = dist[i] + e->v;
                    ft[j] = i;
                    fe[j] = e;
                    if (!Q.inq[j])
                        Q.ins(j);
                }
            }
        }
        return dist[T]!=INF;
    }
    void Augment()
    {
        int i,delta=INF;
        for (i=T;i!=S;i=ft[i])
            if (fe[i]->c < delta)
                delta = fe[i]->c;
        for (i=T;i!=S;i=ft[i])
        {
            fe[i]->c -= delta;
            fe[i]->op->c += delta;
            Costflow += fe[i]->v * delta;
        }
    }
    void SPFAFlow()
    {
        Q.init();
        while (SPFA())
            Augment();
    }
    void solve()
    {
        int i,j;
        for (i=1;i<=N;i++)
            addedge(S,i,1,0);
        for (i=1;i<=N;i++)
            addedge(i+N,T,1,0);
        for (i=1;i<=N;i++)
            for (j=1;j<=N;j++)
                addedge(i,j+N,INF,Sc[i][j]);
        SPFAFlow();
        printf("%d
    ",Costflow);
        memset(V,0,sizeof(V));
        EC=-1;Costflow=0;
        for (i=1;i<=N;i++)
            addedge(S,i,1,0);
        for (i=1;i<=N;i++)
            addedge(i+N,T,1,0);
        for (i=1;i<=N;i++)
            for (j=1;j<=N;j++)
                addedge(i,j+N,INF,-Sc[i][j]);
        SPFAFlow();
        printf("%d
    ",-Costflow);
    }
    int main()
    {
        init();
        solve();
        return 0;
    }
  • 相关阅读:
    十八、mysql 流程控制结构
    十七、mysql 函数
    2.Hibernate批量删除的两种方式
    1.Hibernate比较数字
    1.java.IO.File中与系统相关的静态字段如:“/”
    1.彻底解决Springmvc中文乱码问题
    仿京东导航栏CSS练习
    定位position介绍
    超过固定宽度用...表示
    图标字体和@fontface的用法
  • 原文地址:https://www.cnblogs.com/Aragaki/p/7528904.html
Copyright © 2011-2022 走看看