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
  • 相关阅读:
    ABAP 程序中的类 沧海
    ABAP类的方法(转载) 沧海
    More than 100 ABAP Interview Faq's(2) 沧海
    SAP and ABAP Memory总结 沧海
    ABAP Frequently Asked Question 沧海
    ABAP System Reports(Additional functions) 沧海
    ABAP Questions Commonly Asked 1 沧海
    ABAP Tips and Tricks 沧海
    ABAP System Fields 沧海
    ABAP 面试问题及答案(一):数据库更新及更改 SAP Standard (转) 沧海
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/7000940.html
Copyright © 2011-2022 走看看