zoukankan      html  css  js  c++  java
  • [luoguP2765] 魔术球问题(最大流—最小不相交路径覆盖)

    传送门

    枚举球的个数 num

    如果 i < j && (i + j) 是完全平方数,那么 i -> j' 连一条边

    再加一个超级源点 s,s -> i

    再加一个超级汇点 t,i' -> t

    那么当前可以放的柱子的最小数量就是最小不相交路径数

    如果当前的最小不相交路径数 > num,break

    求最大流的时候别忘了记录方案

    ——代码

      1 #include <cmath>
      2 #include <queue>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <iostream>
      6 #define N 10001
      7 #define M 200001
      8 #define mid 5000
      9 #define min(x, y) ((x) < (y) ? (x) : (y))
     10 
     11 int n, cnt, sum, ans, s, t = mid << 1;
     12 int head[N], to[M], next[M], val[M], suc[N], dis[N];
     13 bool vis[N];
     14 
     15 inline int read()
     16 {
     17     int x = 0, f = 1;
     18     char ch = getchar();
     19     for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
     20     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
     21     return x * f;
     22 }
     23 
     24 inline void add(int x, int y, int z)
     25 {
     26     to[cnt] = y;
     27     val[cnt] = z;
     28     next[cnt] = head[x];
     29     head[x] = cnt++;
     30 }
     31 
     32 inline bool bfs()
     33 {
     34     int i, u, v;
     35     std::queue <int> q;
     36     memset(dis, -1, sizeof(dis));
     37     q.push(s);
     38     dis[s] = 0;
     39     while(!q.empty())
     40     {
     41         u = q.front(), q.pop();
     42         for(i = head[u]; i ^ -1; i = next[i])
     43         {
     44             v = to[i];
     45             if(val[i] && dis[v] == -1)
     46             {
     47                 dis[v] = dis[u] + 1;
     48                 if(v == t) return 1;
     49                 q.push(v);
     50             }
     51         }
     52     }
     53     return 0;
     54 }
     55 
     56 inline int dfs(int u, int maxflow)
     57 {
     58     if(u == t) return maxflow;
     59     int i, v, d, ret = 0;
     60     for(i = head[u]; i ^ -1; i = next[i])
     61     {
     62         v = to[i];
     63         if(val[i] && dis[v] == dis[u] + 1)
     64         {
     65             d = dfs(v, min(val[i], maxflow - ret));
     66             ret += d;
     67             val[i] -= d;
     68             val[i ^ 1] += d;
     69             if(d) suc[u] = v - mid;
     70             if(ret == maxflow) return ret;
     71         }
     72     }
     73     return ret;
     74 }
     75 
     76 int main()
     77 {
     78     int i, j, now, num = 0;
     79     n = read();
     80     memset(head, -1, sizeof(head));
     81     while(1)
     82     {
     83         num++;
     84         add(s, num, 1), add(num, s, 0);
     85         add(num + mid, t, 1), add(t, num + mid, 0);
     86         for(i = 1; i < num; i++)
     87             if(sqrt(i + num) == (int)sqrt(i + num))
     88                 add(i, num + mid, 1), add(num + mid, i, 0);
     89         while(bfs()) sum += dfs(s, 1e9);
     90         if(num - sum > n) break;
     91     }
     92     cnt = 0;
     93     memset(head, -1, sizeof(head));
     94     for(i = 1; i < num; i++)
     95     {
     96         add(s, i, 1), add(i, s, 0);
     97         add(i + mid, t, 1), add(t, i + mid, 0);
     98     }
     99     for(i = 1; i < num; i++)
    100         for(j = 1; j < i; j++)
    101             if(sqrt(i + j) == (int)sqrt(i + j))
    102                 add(j, i + mid, 1), add(i + mid, j, 0);
    103     while(bfs()) dfs(s, 1e9);
    104     printf("%d
    ", num - 1);
    105     for(i = 1; i < num; i++)
    106         if(!vis[i])
    107         {
    108             now = i;
    109             while(now)
    110             {
    111                 printf("%d ", now);
    112                 vis[now] = 1;
    113                 now = suc[now];
    114             }
    115             puts("");
    116         }
    117     return 0;
    118 }
    View Code
  • 相关阅读:
    web端ip定位
    【树状数组2】洛谷P3368
    【树状数组1】 洛谷P3374
    【割点】洛谷P3388
    【二分图匹配】洛谷P3386
    洛谷P4145 上帝造题的七分钟2 / 花神游历各国
    【线段树2】洛谷P3373
    【线段树1】洛谷P3372
    【乘法逆元】洛谷P3811
    【LCA】洛谷P3379
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6931964.html
Copyright © 2011-2022 走看看