zoukankan      html  css  js  c++  java
  • 洛谷P4553 80人环游世界

    题意:有m个人,给定n个城市构成DAG。

    每个城市恰好有vi个人经过,每条边有费用。

    每个人自选起点,终点。

    求最小费用。

    解:

    首先拆点,连边,流量为[vi, vi]。

    然后做有上下界有源汇最小费用可行流即可。

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <queue>
      4 #include <cstring>
      5 #include <cmath>
      6 
      7 const int N = 18000, M = 1000010, INF = 0x3f3f3f3f;
      8 
      9 struct Edge {
     10     int nex, v, c, len;
     11 }edge[M << 1]; int top = 1;
     12 
     13 int e[N], d[N], vis[N], pre[N], flow[N];
     14 std::queue<int> Q;
     15 bool vp[200010];
     16 
     17 inline void add(int x, int y, int z, int w) {
     18     top++;
     19     edge[top].v = y;
     20     edge[top].c = z;
     21     edge[top].len = w;
     22     edge[top].nex = e[x];
     23     e[x] = top;
     24 
     25     top++;
     26     edge[top].v = x;
     27     edge[top].c = 0;
     28     edge[top].len = -w;
     29     edge[top].nex = e[y];
     30     e[y] = top;
     31     return;
     32 }
     33 
     34 inline bool SPFA(int s, int t) {
     35     memset(d, 0x3f, sizeof(d));
     36     d[s] = 0;
     37     flow[s] = INF;
     38     vis[s] = 1;
     39     Q.push(s);
     40     while(!Q.empty()) {
     41         int x = Q.front();
     42         Q.pop();
     43         vis[x] = 0;
     44         for(int i = e[x]; i; i = edge[i].nex) {
     45             int y = edge[i].v;
     46             if(edge[i].c && d[y] > d[x] + edge[i].len) {
     47                 d[y] = d[x] + edge[i].len;
     48                 pre[y] = i;
     49                 flow[y] = std::min(flow[x], edge[i].c);
     50                 if(!vis[y]) {
     51                     vis[y] = 1;
     52                     Q.push(y);
     53                 }
     54             }
     55         }
     56     }
     57     return d[t] < INF;
     58 }
     59 
     60 inline void update(int s, int t) {
     61     int temp = flow[t];
     62     while(t != s) {
     63         int i = pre[t];
     64         edge[i].c -= temp;
     65         edge[i ^ 1].c += temp;
     66         t = edge[i ^ 1].v;
     67     }
     68     return;
     69 }
     70 
     71 inline int solve(int s, int t, int &cost) {
     72     int ans = 0;
     73     cost = 0;
     74     while(SPFA(s, t)) {
     75         ans += flow[t];
     76         cost += flow[t] * d[t];
     77         update(s, t);
     78     }
     79     return ans;
     80 }
     81 
     82 
     83 int main() {
     84 
     85     int n, m;
     86     scanf("%d%d", &n, &m);
     87     int s = 2 * n + 1, t = 2 * n + 2, ss = 2 * n + 3, S = n * 2 + 4, T = n * 2 + 5;
     88     for(int i = 1, x; i <= n; i++) {
     89         scanf("%d", &x);
     90         // add  i  i + n  x
     91         add(S, i + n, x, 0);
     92         add(i, T, x, 0);
     93     }
     94     for(int i = 1, x; i <= n; i++) {
     95         for(int j = i + 1; j <= n; j++) {
     96             scanf("%d", &x);
     97             if(x == -1) {
     98                 continue;
     99             }
    100             add(i + n, j, INF, x);
    101         }
    102         add(ss, i, INF, 0);
    103         add(i + n, t, INF, 0);
    104     }
    105     add(s, ss, m, 0);
    106     add(t, s, INF, 0);
    107     int ans;
    108     solve(S, T, ans);
    109     printf("%d", ans);
    110     return 0;
    111 }
    AC代码
  • 相关阅读:
    win10 安装cmake报错: "Installation directory must be on a local drive"
    python量化笔记16之夏普比率计算公式
    python机器量化之十七:混淆矩阵(confusion_matrix)含义
    使用Aspose.word (Java) 填充word文档数据
    python笔记(十八)机器量化分析—数据采集、预处理与建模
    js 使FORM表单的所有元素不可编辑的示例代码 表
    Web前端面试题:写一个mul函数
    vue + electron 快速入门
    Java新特性stream流
    mycat中间件进行MySQL数据表的水平拆分
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10103414.html
Copyright © 2011-2022 走看看