zoukankan      html  css  js  c++  java
  • 【洛谷 P2754】 [CTSC1999]家园(最大流)

    题目链接
    突然发现Dinic很好写诶。。
    第一次数组开小了,玄学(WA)what?数据范围描述有误?
    分层图,每天为一层。
    把上一天的每个空间站向这一天连一条流量为inf的边,表示可以原地不动。
    把一个周期内上一天上一个和这一天这一个连一条流量为这艘太空船的容量的边,表示去下一站。
    然后每次加一天,看什么时候最大流达到(k)就行了。

    #include <cstdio>
    #include <queue>
    using namespace std; 
    #define INF 2147483647
    inline int read(){
        int s = 0, w = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9'){if(ch == '-')w = -1;ch = getchar();}
        while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0',ch = getchar();
        return s * w;
    }
    const int MAXN = 1000010;
    struct Edge{
        int next, from, to, rest;
    }e[MAXN];
    int head[MAXN], num = 1;
    inline void Add(int from, int to, int flow){
        //printf("%d %d
    ", from, to);
        e[++num] = (Edge){ head[from], from, to, flow }; head[from] = num;
        e[++num] = (Edge){ head[to], to, from, 0 }; head[to] = num;
    }
    int flow[MAXN], pre[MAXN], dfn[MAXN];
    int h[MAXN], p[MAXN], f[100][100];
    int n, m, k, s, t, sum, now, Time;
    queue <int> q;
    int RoadExist(){
        while(q.size()) q.pop();
        flow[s] = INF; pre[t] = 0; q.push(s); dfn[s] = ++Time;
        while(q.size()){
          now = q.front(); q.pop();
          for(int i = head[now]; i; i = e[i].next)
             if(e[i].rest && dfn[e[i].to] != Time)
               dfn[e[i].to] = Time, flow[e[i].to] = min(flow[now], e[i].rest), q.push(e[i].to), pre[e[i].to] = i;
        }
        return pre[t];
    }
    int dinic(){
        int ans = 0;
        while(RoadExist()){
          ans += flow[t];
          now = t;
          while(now != s){
            e[pre[now]].rest -= flow[t];
            e[pre[now] ^ 1].rest += flow[t];
            now = e[pre[now]].from;
          }
        }
        return ans; 
    }
    int main(){
        n = read() + 2; m = read(); k = read();
        s = 99999; t = 100000;
        for(int i = 1; i <= m; ++i){
           h[i] = read(); p[i] = read();
           for(int j = 0; j < p[i]; ++j)
              f[i][j] = read() + 1;
        }
        Add(s, 1, INF); Add(0, t, INF); 
        for(int i = 1; i <= 500; ++i){
           Add(s, n * i + 1, INF); Add(n * i, t, INF);
           for(int j = 0; j < n; ++j) Add(n * (i - 1) + j, n * i + j, INF);
           for(int j = 1; j <= m; ++j){
              int x = f[j][(i - 1) % p[j]], y = f[j][i % p[j]];
              Add((i - 1) * n + x, i * n + y, h[j]);
           }
           if((sum += dinic()) >= k){
             printf("%d
    ", i);
             return 0;
           }
        }
        printf("0
    ");
        return 0;
    }
    
    
  • 相关阅读:
    Oracle RMAN快速入门指南
    防止SQL注入
    脚本获取参数 
    回车下一个
    DataTable
    C# Eval
    C#过滤所有HTML代码的函数
    反射
    gridview格式化问题
    绑定
  • 原文地址:https://www.cnblogs.com/Qihoo360/p/10124880.html
Copyright © 2011-2022 走看看