zoukankan      html  css  js  c++  java
  • [codeVS1916] 负载平衡问题(最小费用流,拆点)

    题目链接:http://codevs.cn/problem/1916/

    n个点之间可以相互传递值,每传递一次步骤+1。最终希望所有点的值相同,问最少步骤。

    最终所有值应当是平均数avg,如何在两个相邻点之间传输值?可以先拆点,再建边:

    将每一个点拆成两个点(两个点集分别记为①和②),同点②到①之间的容量为inf,费用为0。

    拆完点后,按照要求每一个①点连向相邻两个点的②点,容量为inf,费用为1。

    需要注意的是,保证移动完每一步可以判断是否能直接流向汇点,所以要在①点集合中向汇点建边,容量为avg,费用为0。

    这里建图建挫了,大致是这样:

    跑最小费用流就可以了。

     PS:这么看来BNU校赛的A题也可以这么建模(虽然贪心过的)。

    附链接,可以思考:https://www.bnuoj.com/v3/contest_show.php?cid=9056#problem/A

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 typedef long long LL;
      5 typedef struct Node {
      6     int u, v, next;
      7     LL c, w;
      8 }Node;
      9 const int maxn = 210;
     10 const int maxm = 4010;
     11 const LL mod = 0x3f3f3f3fLL;
     12 const LL inf = (1LL<<55);
     13 int tot, head[maxn];
     14 LL dist[maxn];
     15 LL cost, flow;
     16 Node e[maxm];
     17 int pre[maxn];
     18 bool visit[maxn];
     19 queue<int> Q;
     20 int S, T, N;
     21 
     22 void adde(int u, int v, LL c, LL w) {
     23     e[tot].u = u; e[tot].v = v; e[tot].c = c; e[tot].w = w; e[tot].next = head[u]; head[u] = tot++;
     24     e[tot].u = v; e[tot].v = u; e[tot].c = 0; e[tot].w = -w; e[tot].next = head[v]; head[v] = tot++;
     25 }
     26 bool spfa(int s, int t, int n) {
     27     int i;
     28     for(i = 0; i <= n; i++) {
     29         dist[i] = inf;
     30         visit[i] = 0;
     31         pre[i] = -1;
     32     }
     33     while(!Q.empty()) Q.pop();
     34     Q.push(s);
     35     visit[s] = true;
     36     dist[s] = 0;
     37     pre[s] = -1;
     38     while(!Q.empty()) {
     39         int u = Q.front();
     40         visit[u] = false;
     41         Q.pop();
     42         for(int j = head[u]; j != -1; j = e[j].next) {
     43             if(e[j].c > 0 && dist[u] + e[j].w < dist[e[j].v]) {
     44                 dist[e[j].v] = dist[u] + e[j].w;
     45                 pre[e[j].v] = j;
     46                 if(!visit[e[j].v]) {
     47                     Q.push(e[j].v);
     48                     visit[e[j].v] = true;
     49                 }
     50             }
     51         }
     52     }
     53     if(dist[t] == inf) return false;
     54     else return true;
     55 }
     56 LL ChangeFlow(int t) {
     57     LL det = mod;
     58     int u = t;
     59     while(~pre[u]) {
     60         u = pre[u];
     61         det = min(det, e[u].c);
     62         u = e[u].u;
     63     }
     64     u = t;
     65     while(~pre[u]) {
     66         u = pre[u];
     67         e[u].c -= det;
     68         e[u ^ 1].c += det;
     69         u = e[u].u;
     70     }
     71     return det;
     72 }
     73 LL MinCostFlow(int s, int t, int n) {
     74     LL mincost, maxflow;
     75     mincost = maxflow = 0;
     76     while(spfa(s, t, n)) {
     77         LL det = ChangeFlow(t);
     78         mincost += det * dist[t];
     79         maxflow += det;
     80     }
     81     cost = mincost;
     82     flow = maxflow;
     83     return mincost;
     84 }
     85 
     86 int n;
     87 int a[maxn];
     88 
     89 int main() {
     90     LL avg = 0;
     91     scanf("%d", &n);
     92     for(int i = 1; i <= n; i++) {
     93         scanf("%d", &a[i]);
     94         avg += a[i];
     95     }
     96     avg /= n;
     97     tot = 0;
     98     memset(head, -1, sizeof(head));
     99     S = 0, T = 2 * n + 1; N = T + 1;
    100     for(int i = 1; i <= n; i++) {
    101         adde(0, i, a[i], 0);
    102         adde(i+n, i, inf, 0);
    103         adde(i, T, (LL)avg, 0);
    104     }
    105     for(int i = 1; i < n; i++) adde(i, i+n+1, inf, 1);
    106     adde(n, n+1, inf, 1);
    107     for(int i = 2; i <= n; i++) adde(i, i+n-1, inf, 1);
    108     adde(1, 2*n, inf, 1);
    109     cout << MinCostFlow(S, T, N) << endl;
    110     return 0;
    111 }
  • 相关阅读:
    atitit.按钮光标滑过高亮切换以及其他动态效果的实现css html js attilax总结
    atitit. 文件上传带进度条 atiUP 设计 java c# php
    atitit.新增编辑功能 跟orm的实现 attilax p31
    atitit. java jsoup html table的读取解析 总结
    atitit.设计文档操作日志的实现
    atitit.资源释放机制attilax总结
    (转)Android的消息机制,用Android线程间通信的Message机制,Android中Handler的使用方法——在子线程中更新界面,handler机制
    (转)Android笔记handler机制
    (转)数据存储
    (转)android连网详解
  • 原文地址:https://www.cnblogs.com/kirai/p/6768379.html
Copyright © 2011-2022 走看看