[Maximum flow, dinic] P2765 magic ball problem

  1 #include<iostream>
  2 #include<queue>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<cmath>
  6 using namespace std;
  7 
  8 const int INF = 0x3f3f3f3f;
  9 const int maxn = 100100;
 10 
 11 int d[maxn];
 12 int now[maxn];
 13 const int st = 0, ed = 100010;
 14 int n;
 15 int cnt = 1;
 16 int tot;
 17 int num;
 18 int ans[maxn];
 19 bool vis[maxn];
 20 int nxt[maxn];
 21 
 22 struct Edge
 23 {
 24     int v, nxt;
 25     int w;
 26 }e[maxn];
 27 
 28 int head[maxn];
 29 
 30 void add_dinic(int u, int v)
 31 {
 32     e[++cnt].v = v;
 33     e[cnt].w = 0;
 34     e[cnt].nxt = head[u];
 35     head[u] = cnt;
 36 }
 37 
 38 void add(int u, int v, int w)
 39 {
 40     e[++cnt].v = v;
 41     e[cnt].nxt = head[u];
 42     head[u] = cnt;
 43     e[cnt].w = w;
 44     add_dinic(v, u);
 45 }
 46 
 47 int dfs_dinic(int x, int flow)
 48 {
 49     if (x == ed) return flow;
 50     int res = 0;
 51     for (int i = now[x]; i != -1; i = e[i].nxt)
 52     {
 53         int v = e[i].v;
 54         if (d[v] + 1 == d[x] && e[i].w > 0)
 55         {
 56             int k = dfs_dinic(v, min(e[i].w, flow));
 57             if (k >= 0) nxt[x >> 1] = v >> 1;
 58             res += k;
 59             flow -= k;
 60             e[i].w -= k;
 61             e[i ^ 1].w += k;
 62             if (!flow) break;
 63         }
 64     }
 65     return res;
 66 }
 67 
 68 bool bfs_dinic()
 69 {
 70     memset(d, 0, sizeof(d));
 71     queue<int>q;
 72     q.push(ed);
 73     d[ed] = 1;
 74     while (!q.empty())
 75     {
 76         int u = q.front();
 77         q.pop();
 78         for (int i = head[u]; i != -1; i = e[i].nxt)
 79         {
 80             int v = e[i].v;
 81             if (!d[v] && e[i ^ 1].w > 0)
 82             {
 83                 q.push(v);
 84                 d[v] = d[u] + 1;
 85             }
 86         }
 87     }
 88     return d[st] > 0;
 89 }
 90 
 91 int dinic()
 92 {
 93     int flow = 0;
 94     while (bfs_dinic())
 95     {
 96         for (int i = 0; i <= ed; i++) now[i] = head[i];
 97         flow += dfs_dinic(st, INF);
 98     }
 99     return flow;
100 }
101 
102 int main()
103 {
104     memset(head, -1, sizeof(head));
105     memset(nxt, -1, sizeof(nxt));
106     cin >> n;
107     cnt = 1;
108     while (tot <= n)
109     {
110         num++;
111         add(st, num << 1, 1);
112         add(num << 1 | 1, ed, 1);
113         for (int i = sqrt(num) + 1; i * i < (num << 1); ++i)
114             add((i * i - num) << 1, num << 1 | 1, 1);
115         int k = dinic();
116         if (!k) ans[++tot] = num;
117     }
118     cout << --num << endl; 
119     for (int i = 1; i <= n; i++)
120     {
121         if (vis[ans[i]]) continue;
122         int x = ans[i];
123         cout << x << " ";
124         vis[x] = true;
125         while ((~nxt[x]) && nxt[x] != (ed >> 1) && nxt[x])
126         {
127             x = nxt[x]; 
128             vis[x] = true;
129             cout << x << " ";
130         }
131         cout << endl;
132     }
133 
134 }
View Code

 

Guess you like

Origin www.cnblogs.com/thjkhdf12/p/11828500.html