CCF(引水入城:60分):最大流+ISAPアルゴリズム

3276 ワード

水を城に引き込む
201703-5
  • これは問題の分析から見ると最大ストリームの問題に似ており、1つのスーパーソースポイントと1つのスーパーポイントを増やすだけで、問題の意味に従って最大ストリームアルゴリズムを走ることができます.
  • データ量が大きすぎるので、タイムアウトするに違いありません.しかし、実行可能な解決策は考えられなかった.
  • #include
    using namespace std;
    const long long INF=0XFFFFFFFF;
    const int maxn=4500016;
    /* run this program using the console pauser or add your own getch, system("pause") or input loop */
    struct Edge {
      int from, to;long long cap, flow;
      Edge(int u, int v, long long c, long long f) : from(u), to(v), cap(c), flow(f) {}
    };
    bool operator edges;
      vector G[maxn];
      bool vis[maxn];
      int d[maxn];
      int cur[maxn];
      int p[maxn];
      int num[maxn];
    
      void AddEdge(int from, int to, long long cap) {
        edges.push_back(Edge(from, to, cap, 0));
        edges.push_back(Edge(to, from, 0, 0));
        m = edges.size();
        G[from].push_back(m - 2);
        G[to].push_back(m - 1);
      }
    
      bool BFS() {
        memset(vis, 0, sizeof(vis));
        queue Q;
        Q.push(t);
        vis[t] = 1;
        d[t] = 0;
        while (!Q.empty()) {
          int x = Q.front();
          Q.pop();
          for (int i = 0; i < G[x].size(); i++) {
            Edge& e = edges[G[x][i] ^ 1];
            if (!vis[e.from] && e.cap > e.flow) {
              vis[e.from] = 1;
              d[e.from] = d[x] + 1;
              Q.push(e.from);
            }
          }
        }
        return vis[s];
      }
    
      void init(int n) {
        this->n = n;
        for (int i = 0; i <= n; i++) G[i].clear();
        edges.clear();
      }
    
      int Augment() {
        int x = t;long long a = INF;
        while (x != s) {
          Edge& e = edges[p[x]];
          a = min(a, e.cap - e.flow);
          x = edges[p[x]].from;
        }
        x = t;
        while (x != s) {
          edges[p[x]].flow += a;
          edges[p[x] ^ 1].flow -= a;
          x = edges[p[x]].from;
        }
        return a;
      }
    
     long long Maxflow(int s, int t) {
        this->s = s;
        this->t = t;
        long long flow = 0;
        BFS();
        memset(num, 0, sizeof(num));
        for (int i = 0; i <= n; i++) num[d[i]]++;
        int x = s;
        memset(cur, 0, sizeof(cur));
        while (d[s] < n) {
          if (x == t) {
            flow += Augment();
            x = s;
          }
          int ok = 0;
          for (int i = cur[x]; i < G[x].size(); i++) {
            Edge& e = edges[G[x][i]];
            if (e.cap > e.flow && d[x] == d[e.to] + 1) {
              ok = 1;
              p[e.to] = G[x][i];
              cur[x] = i;
              x = e.to;
              break;
            }
          }
          if (!ok) {
            int m = n - 1;
            for (int i = 0; i < G[x].size(); i++) {
              Edge& e = edges[G[x][i]];
              if (e.cap > e.flow) m = min(m, d[e.to]);
            }
            if (--num[d[x]] == 0) break;
            num[d[x] = m + 1]++;
            cur[x] = 0;
            if (x != s) x = edges[p[x]].from;
          }
        }
        return flow;
      }
    }ek;
    long long a,b,mod,x;
    int n,m;
    int compute(){
        return x=(a*x+b)%mod;
    }
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin>>n>>m>>a>>b>>mod>>x;
        int s=0,t=n*m+1;
        ek.init(n*m+1);
        for(int i=0;i

    転載先:https://www.cnblogs.com/GarrettWale/p/11484773.html