zoukankan      html  css  js  c++  java
  • [luoguP2754] 星际转移问题(最大流)

    传送门

    不同的时间每个飞船所在的地点不同,给我们启示按照时间构建分层图。

    同一个地点 x <x, dayi - 1> -> <x, dayi> 连一条容量为 INF 的边,因为人们可以在一个地点等待

    艘飞船的路径 如果 a 的下一站是 b,那么 <a, dayi - 1> -> <b, dayi> 连一条容量为该飞船容量的边,表示可以 a 坐飞船到 b

    增加超级源点 s,s 和地球连一条容量为 k 的边

    增加超级汇点 t,月球的每一天都和 t 连一条容量为 INF 的边

    枚举天数,跑最大流,直到 max_flow == k,输出天数

    对于判断是否能到达,用并查集判断连通性

    ——代码

      1 #include <queue>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <iostream>
      5 #define N 1000001
      6 #define INF 1e9
      7 #define min(x, y) ((x) < (y) ? (x) : (y))
      8 
      9 int n, m, k, s, t, cnt, sum;
     10 int f[N], c[N], p[N], b[101][101], dis[N];
     11 int head[N], to[N << 1], next[N << 1], val[N << 1];
     12 
     13 inline int C(int t, int x)
     14 {
     15     return t * (n + 2) + x;
     16 } 
     17 
     18 inline int read()
     19 {
     20     int x = 0, f = 1;
     21     char ch = getchar();
     22     for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
     23     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
     24     return x * f;
     25 }
     26 
     27 inline int find(int x)
     28 {
     29     return x == f[x] ? x : f[x] = find(f[x]);
     30 }
     31 
     32 inline void add(int x, int y, int z)
     33 {
     34     to[cnt] = y;
     35     val[cnt] = z;
     36     next[cnt] = head[x];
     37     head[x] = cnt++;
     38 }
     39 
     40 inline bool bfs()
     41 {
     42     int i, u, v;
     43     std::queue <int> q;
     44     memset(dis, -1, sizeof(dis));
     45     q.push(s);
     46     dis[s] = 0;
     47     while(!q.empty())
     48     {
     49         u = q.front(), q.pop();
     50         for(i = head[u]; i ^ -1; i = next[i])
     51         {
     52             v = to[i];
     53             if(val[i] && dis[v] == -1)
     54             {
     55                 dis[v] = dis[u] + 1;
     56                 if(v == t) return 1;
     57                 q.push(v);
     58             }
     59         }
     60     }
     61     return 0;
     62 }
     63 
     64 inline int dfs(int u, int maxflow)
     65 {
     66     if(u == t) return maxflow;
     67     int v, d, ret = 0;
     68     for(int i = head[u]; i ^ -1; i = next[i])
     69     {
     70         v = to[i];
     71         if(val[i] && dis[v] == dis[u] + 1)
     72         {
     73             d = dfs(v, min(val[i], maxflow - ret));
     74             ret += d;
     75             val[i] -= d;
     76             val[i ^ 1] += d;
     77             if(ret == maxflow) return ret;
     78         }
     79     }
     80     if(ret ^ maxflow) dis[u] = -1;
     81     return ret;
     82 }
     83 
     84 int main()
     85 {
     86     int i, j, x, y, d;
     87     n = read();
     88     m = read();
     89     k = read();
     90     s = N - 1, t = N - 2;
     91     for(i = 1; i <= n + 2; i++) f[i] = i;
     92     for(i = 1; i <= m; i++)
     93     {
     94         c[i] = read();
     95         p[i] = read();
     96         for(j = 0; j < p[i]; j++)
     97         {
     98             b[i][j] = read() + 2;
     99             if(j)
    100             {
    101                 x = find(b[i][j - 1]);
    102                 y = find(b[i][j]);
    103                 if(x ^ y) f[x] = y;
    104             }
    105         }
    106     }
    107     if(find(1) ^ find(2))
    108     {
    109         printf("0
    ");
    110         return 0;
    111     }
    112     d = 0;
    113     memset(head, -1, sizeof(head));
    114     add(s, 2, k);
    115     add(2, s, 0);
    116     while(1)
    117     {
    118         d++;
    119         for(i = 1; i <= n + 2; i++)
    120         {
    121             add(C(d - 1, i), C(d, i), INF);
    122             add(C(d, i), C(d - 1, i), 0);
    123         }
    124         for(i = 1; i <= m; i++)
    125         {
    126             add(C(d - 1, b[i][(d - 1) % p[i]]), C(d, b[i][d % p[i]]), c[i]);
    127             add(C(d, b[i][d % p[i]]), C(d - 1, b[i][(d - 1) % p[i]]), 0);
    128         }
    129         add(C(d, 1), t, INF);
    130         add(t, C(d, 1), 0);
    131         while(bfs()) sum += dfs(s, INF);
    132         if(sum == k)
    133         {
    134             printf("%d
    ", d);
    135             return 0;
    136         }
    137     }
    138 }
    View Code
  • 相关阅读:
    go 基本包
    go 包
    算法笔记--数据结构--链表
    算法笔记--数据结构--队列
    算法笔记--标准模板库STL--pair
    算法笔记--标准模板库STL--stack
    算法笔记--标准模板库STL--priority_queue
    算法笔记--标准模板库STL--queue
    初识pair
    lower_bound实现离散化
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/7000940.html
Copyright © 2011-2022 走看看