• 分配问题 【网络流24题】


    输入输出样例

    输入 #1
    5
    2 2 2 1 2
    2 3 1 2 4
    2 0 1 1 1
    2 3 4 3 3
    3 2 1 2 1
    输出 #1
    5
    14

     思路

      易发现可以把人和任务分成两个阵营

      这样就是一个标准的二分图

      对于这个二分图跑最小费用最大流和最大费用最小流即可

      把 S 到每个人的容量都设置为1即可保证每个人只做一件事

      对于每个人到每个任务的花费自然是 Cij

    CODE

      1 #include <bits/stdc++.h>
      2 #define dbg(x) cout << #x << "=" << x << endl
      3 #define eps 1e-8
      4 #define pi acos(-1.0)
      5 
      6 using namespace std;
      7 typedef long long LL;
      8 const int maxn = 1e5 +7;
      9 const int inf  = 0x3f3f3f3f;
     10 
     11 int n, m, s, t;
     12 int head[maxn],pre[maxn],inq[maxn],dis[maxn];
     13 int a[maxn];
     14 int cnt = 1;
     15 int path[2][maxn];
     16 int mincost = 0, maxflow = 0;
     17 struct edge {
     18     int u,to,nxt,w,c;
     19 }e[maxn << 1];
     20 int tot[5];
     21 
     22 template<class T>inline void read(T &res)
     23 {
     24     char c;T flag=1;
     25     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
     26     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
     27 }
     28 
     29 inline void BuildGraph(int u, int v, int w, int cost)
     30 {
     31     e[++cnt] = (edge){u, v, head[u], w,  cost}, head[u] = cnt;
     32     e[++cnt] = (edge){v, u, head[v], 0, -cost}, head[v] = cnt;///反向边
     33 }
     34 
     35 queue<int> q;
     36 
     37 inline void init() {
     38     memset(head, 0, sizeof(head));
     39     memset(pre, 0, sizeof(pre));
     40     memset(inq, 0, sizeof(inq));
     41     memset(dis, 0, sizeof(dis));
     42     memset(e, 0, sizeof(e));
     43     while(!q.empty()) {
     44         q.pop();
     45     }
     46     mincost = maxflow = 0;
     47     cnt = 1;
     48 }
     49 
     50 bool SPFA(int x)
     51 {
     52     memset(inq, 0, sizeof(inq));
     53     for(int i = s; i <= t; i++) {
     54         dis[i] = inf;
     55     }
     56     q.push(x);
     57     dis[x] = 0;
     58     inq[x] = 1;
     59     while(!q.empty()) {
     60         int u = q.front();
     61         q.pop();
     62         inq[u] = 0;
     63         for(int i = head[u]; i; i = e[i].nxt) {
     64             int v = e[i].to, w = e[i].c;
     65             if(e[i].w > 0) {
     66                 if(dis[u] + w < dis[v]) {
     67                     dis[v] = dis[u] + w;
     68                     pre[v] = i;
     69                     if(!inq[v]) {
     70                         q.push(v);
     71                         inq[v] = 1;
     72                     }
     73                 }
     74             }
     75         }
     76     }
     77     if(dis[t] == inf)
     78         return 0;
     79     return 1;
     80 }
     81 
     82 void MCMF()
     83 {
     84     while(SPFA(s)) {
     85         int temp = inf;
     86         for(int i = pre[t]; i; i = pre[e[i].u]) {
     87             temp = min(temp, e[i].w);
     88         }
     89         for(int i = pre[t]; i; i = pre[e[i].u]) {
     90             e[i].w   -= temp;
     91             e[i^1].w += temp;
     92             mincost += e[i].c * temp;
     93             //printf("e[%d].c:%d
    ",i, e[i].c);
     94             //printf("ans:%d
    ",ans);
     95         }
     96         //maxflow += temp;
     97     }
     98 }
     99 
    100 int xx[107][107];
    101 
    102 int main()
    103 {
    104     //freopen("data.txt", "r", stdin);
    105     read(n);
    106     s = 0, t = n << 1 | 1;
    107     for ( int i = 1; i <= n; ++i ) {
    108         BuildGraph(s, i, 1, 0);
    109         for ( int j = 1; j <= n; ++j ) {
    110             read(xx[i][j]);
    111             BuildGraph(i, j + n, 1, xx[i][j]);
    112         }
    113         BuildGraph(i + n, t, 1, 0);
    114     }
    115     MCMF();
    116     int ans = mincost;
    117     cout << ans << endl;
    118     //dbg(maxflow);
    119     init();
    120     s = 0, t = n << 1 | 1;
    121     for ( int i = 1; i <= n; ++i ) {
    122         BuildGraph(s, i, 1, 0);
    123         for ( int j = 1; j <= n; ++j ) {
    124             BuildGraph(i, j + n, 1, -xx[i][j]);
    125         }
    126         BuildGraph(i + n, t, 1, 0);
    127     }
    128     MCMF();
    129     ans = -mincost;
    130     cout << ans << endl;
    131     //dbg(maxflow);
    132     return 0;
    133 }
    View Code
    #include <bits/stdc++.h>
    #define dbg(x) cout << #x << "=" << x << endl
    #define eps 1e-8
    #define pi acos(-1.0)

    using namespace std;
    typedef long long LL;
    const int maxn = 1e5 +7;
    const int inf  = 0x3f3f3f3f;

    int n, m, s, t;
    int head[maxn],pre[maxn],inq[maxn],dis[maxn];
    int a[maxn];
    int cnt = 1;
    int path[2][maxn];
    int mincost = 0, maxflow = 0;
    struct edge {
        int u,to,nxt,w,c;
    }e[maxn << 1];
    int tot[5];

    template<class T>inline void read(&res)
    {
        char c;T flag=1;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
        while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    }

    inline void BuildGraph(int u, int v, int w, int cost)
    {
        e[++cnt] = (edge){u, v, head[u], w,  cost}, head[u] = cnt;
        e[++cnt] = (edge){v, u, head[v], 0, -cost}, head[v] = cnt;///反向边
    }

    queue<int> q;

    inline void init() {
        memset(head, 0, sizeof(head));
        memset(pre, 0, sizeof(pre));
        memset(inq, 0, sizeof(inq));
        memset(dis, 0, sizeof(dis));
        memset(e, 0, sizeof(e));
        while(!q.empty()) {
            q.pop();
        }
        mincost = maxflow = 0;
        cnt = 1;
    }

    bool SPFA(int x)
    {
        memset(inq, 0, sizeof(inq));
        for(int i = s; i <= t; i++) {
            dis[i] = inf;
        }
        q.push(x);
        dis[x] = 0;
        inq[x] = 1;
        while(!q.empty()) {
            int u = q.front();
            q.pop();
            inq[u] = 0;
            for(int i = head[u]; i; i = e[i].nxt) {
                int v = e[i].to, w = e[i].c;
                if(e[i].w > 0) {
                    if(dis[u] + w < dis[v]) {
                        dis[v] = dis[u] + w;
                        pre[v] = i;
                        if(!inq[v]) {
                            q.push(v);
                            inq[v] = 1;
                        }
                    }
                }
            }
        }
        if(dis[t] == inf)
            return 0;
        return 1;
    }

    void MCMF()
    {
        while(SPFA(s)) {
            int temp = inf;
            for(int i = pre[t]; i; i = pre[e[i].u]) {
                temp = min(temp, e[i].w);
            }
            for(int i = pre[t]; i; i = pre[e[i].u]) {
                e[i].w   -= temp;
                e[i^1].w += temp;
                mincost += e[i].c * temp;
                //printf("e[%d].c:%d ",i, e[i].c);
                //printf("ans:%d ",ans);
            }
            //maxflow += temp;
        }
    }

    int xx[107][107];

    int main()
    {
        //freopen("data.txt", "r", stdin);
        read(n);
        s = 0, t = n << 1 | 1;
        for ( int i = 1; i <= n; ++) {
            BuildGraph(s, i, 1, 0);
            for ( int j = 1; j <= n; ++) {
                read(xx[i][j]);
                BuildGraph(i, j + n, 1, xx[i][j]);
            }
            BuildGraph(+ n, t, 1, 0);
        }
        MCMF();
        int ans = mincost;
        cout << ans << endl;
        //dbg(maxflow);
        init();
        s = 0, t = n << 1 | 1;
        for ( int i = 1; i <= n; ++) {
            BuildGraph(s, i, 1, 0);
            for ( int j = 1; j <= n; ++) {
                BuildGraph(i, j + n, 1, -xx[i][j]);
            }
            BuildGraph(+ n, t, 1, 0);
        }
        MCMF();
        ans = -mincost;
        cout << ans << endl;
        //dbg(maxflow);
        return 0;
    }
  • 相关阅读:
    Python练习题 016:猴子吃桃
    Date() 及其 如何验证用户输入的日期是合法的
    关于事件触发的一个小tips
    KVO监听导航栏
    使用CoreText动态下载更换字体
    UICollectionView 的使用
    echarts散点图搭配时间轴
    使用百度echarts画图表的步骤
    canvas画图中drawImage使用
    html5canvas简单画图
  • 原文地址:https://www.cnblogs.com/orangeko/p/12798416.html
Copyright © 2020-2023  润新知