zoukankan      html  css  js  c++  java
  • 魔术球问题 【网络流24题】【建图技巧】

    输入输出样例

    输入 #1
    4
    输出 #1
    11
    1 8
    2 7 9
    3 6 10
    4 5 11

    思路

      既然是网络流24题自然用网络流的思想来建图

      考虑一个问题,

      如果把每个柱子考虑成一个特定路径,

      把柱子上的球看作是路径经过的点号,

      为了要在固定的路线上经过更多的点,

      则可以很清晰的知道这是一个最小路径覆盖问题。

      看出了方向之后自然是思考建图:

      大家都清楚网络流擅长解决此类有限制条件的线性规划问题。

      自然要先分析如何把限制条件转化成图上点与点之间的关系上去。

      首先,先枚举球的个数。竟然没有T

      把点逐渐加到路径上,

      因为每个点既要和S连也要和T连,

      还要和其他点权和为完全平方数的点相连,

      自然考虑拆点。

      通过画图容易发现:

      1、S -> i入, i出 -> T,容量为1

      2、i入 -> j出

      当不断加点把图跑满时,再加点不会更新最大流

      这时就应该引入新的路径,也就是增加柱子个数

      直到柱子个数 = n

     

    CODE

      1 #include <bits/stdc++.h>
      2 #define dbg(x) cout << #x << "=" << x << endl
      3 #define eps 1e-8
      4 #define pi acos(-1.0)
      5 
      6 using namespace std;
      7 typedef long long LL;
      8 
      9 const int inf = 0x3f3f3f3f;
     10 
     11 template<class T>inline void read(T &res)
     12 {
     13     char c;T flag=1;
     14     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
     15     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
     16 }
     17 
     18 namespace _buff {
     19     const size_t BUFF = 1 << 19;
     20     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
     21     char getc() {
     22         if (ib == ie) {
     23             ib = ibuf;
     24             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
     25         }
     26         return ib == ie ? -1 : *ib++;
     27     }
     28 }
     29 
     30 int qread() {
     31     using namespace _buff;
     32     int ret = 0;
     33     bool pos = true;
     34     char c = getc();
     35     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
     36         assert(~c);
     37     }
     38     if (c == '-') {
     39         pos = false;
     40         c = getc();
     41     }
     42     for (; c >= '0' && c <= '9'; c = getc()) {
     43         ret = (ret << 3) + (ret << 1) + (c ^ 48);
     44     }
     45     return pos ? ret : -ret;
     46 }
     47 
     48 const int maxn = 200007;
     49 
     50 int n, m;
     51 int s, t;
     52 
     53 struct edge{
     54     int from,to;
     55     LL cap,flow;
     56 };
     57 
     58 int Pre[maxn << 1], Nxt[maxn << 1];
     59 bool vis[maxn << 1];
     60 
     61 struct DINIC {
     62     int head[maxn << 1], nxt[maxn << 1], edge[maxn << 1], cnt;
     63     int cap[maxn << 1], depth[maxn << 1];
     64 
     65     void init() {
     66         cnt = 1;
     67         memset(head, 0, sizeof(head));
     68     }
     69 
     70     void BuildGraph(int u, int v, int w) {
     71         ++cnt;
     72         edge[cnt] = v;
     73         nxt[cnt] = head[u];
     74         cap[cnt] = w;
     75         head[u] = cnt;
     76 
     77         ++cnt;
     78         edge[cnt] = u;
     79         nxt[cnt] = head[v];
     80         cap[cnt] = 0;
     81         head[v] = cnt;
     82     }
     83 
     84     queue<int> q;
     85 
     86     bool bfs() {
     87         memset(depth, 0, sizeof(depth));
     88         depth[s] = 1;
     89         q.push(s);
     90         while(!q.empty()) {
     91             int u = q.front();
     92             q.pop();
     93             for ( int i = head[u]; i; i = nxt[i] ) {
     94                 int v = edge[i];
     95                 if(depth[v]) {
     96                     continue;
     97                 }
     98                 if(cap[i]) {
     99                     depth[v] = depth[u] + 1;
    100                     q.push(v);
    101                 }
    102             }
    103         }
    104         return depth[t];
    105     }
    106 
    107     int dfs(int u, int dist) {
    108         if(u == t) {
    109             return dist;
    110         }
    111         int flow = 0;
    112         for ( int i = head[u]; i && dist; i = nxt[i] ) {
    113             if(cap[i] == 0)
    114                 continue;
    115             int v = edge[i];
    116             if(depth[v] != depth[u] + 1) {
    117                 continue;
    118             }
    119             int res = dfs(v, min(cap[i], dist));
    120             cap[i] -= res;
    121             cap[i ^ 1] += res;
    122             //printf("cap[%d]:%d
    ",t, cap[t]);
    123             dist -= res;
    124             flow += res;
    125             Nxt[u / 2] = v / 2;
    126         }
    127         return flow;
    128     }
    129 
    130     int maxflow() {
    131         int ans = 0;
    132         while(bfs()) {
    133             ans += dfs(s, inf);
    134         }
    135         return ans;
    136     }
    137 } dinic;
    138 
    139 int main()
    140 {
    141     //freopen("data.txt", "r", stdin);
    142     read(n);
    143     dinic.init();
    144     s = 0, t = 1e5 + 7;
    145     int balls = 0, coll = 0;
    146     while(coll <= n) {
    147         ++balls;
    148         dinic.BuildGraph(s, balls * 2, 1);
    149         dinic.BuildGraph(balls * 2 + 1, t, 1);
    150         for ( int i = sqrt(balls) + 1; i * i < (balls * 2); ++i ) {
    151             dinic.BuildGraph((i * i - balls) * 2, balls * 2 + 1, 1);
    152         }
    153         int maxflow = dinic.maxflow();
    154         if(maxflow == 0) {
    155             ++coll;
    156             Pre[coll] = balls;
    157         }
    158     }
    159     printf("%d
    ",balls - 1);
    160     for ( int i = 1; i <= n; ++i ) {
    161         if(!vis[Pre[i]]) {
    162             for ( int u = Pre[i]; u && u != (t / 2); u = Nxt[u] ) {
    163                 vis[u] = true;
    164                 printf("%d ",u);
    165             }
    166             puts("");
    167         }
    168     }
    169     return 0;
    170 }
    View Code
    #include <bits/stdc++.h>
    #define dbg(x) cout << #x << "=" << x << endl
    #define eps 1e-8
    #define pi acos(-1.0)

    using namespace std;
    typedef long long LL;

    const int inf = 0x3f3f3f3f;

    template<class T>inline void read(&res)
    {
        char c;T flag=1;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
        while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    }

    namespace _buff {
        const size_t BUFF = 1 << 19;
        char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
        char getc() {
            if (ib == ie) {
                ib = ibuf;
                ie = ibuf + fread(ibuf, 1, BUFF, stdin);
            }
            return ib == ie ? -1 : *ib++;
        }
    }

    int qread() {
        using namespace _buff;
        int ret = 0;
        bool pos = true;
        char c = getc();
        for (; (< '0' || c > '9') && c != '-'; c = getc()) {
            assert(~c);
        }
        if (== '-') {
            pos = false;
            c = getc();
        }
        for (; c >= '0' && c <= '9'; c = getc()) {
            ret = (ret << 3) + (ret << 1) + (^ 48);
        }
        return pos ? ret : -ret;
    }

    const int maxn = 200007;

    int n, m;
    int s, t;

    struct edge{
        int from,to;
        LL cap,flow;
    };

    int Pre[maxn << 1], Nxt[maxn << 1];
    bool vis[maxn << 1];

    struct DINIC {
        int head[maxn << 1], nxt[maxn << 1], edge[maxn << 1], cnt;
        int cap[maxn << 1], depth[maxn << 1];

        void init() {
            cnt = 1;
            memset(head, 0, sizeof(head));
        }

        void BuildGraph(int u, int v, int w) {
            ++cnt;
            edge[cnt] = v;
            nxt[cnt] = head[u];
            cap[cnt] = w;
            head[u] = cnt;

            ++cnt;
            edge[cnt] = u;
            nxt[cnt] = head[v];
            cap[cnt] = 0;
            head[v] = cnt;
        }

        queue<int> q;

        bool bfs() {
            memset(depth, 0, sizeof(depth));
            depth[s] = 1;
            q.push(s);
            while(!q.empty()) {
                int u = q.front();
                q.pop();
                for ( int i = head[u]; i; i = nxt[i] ) {
                    int v = edge[i];
                    if(depth[v]) {
                        continue;
                    }
                    if(cap[i]) {
                        depth[v] = depth[u] + 1;
                        q.push(v);
                    }
                }
            }
            return depth[t];
        }

        int dfs(int u, int dist) {
            if(== t) {
                return dist;
            }
            int flow = 0;
            for ( int i = head[u]; i && dist; i = nxt[i] ) {
                if(cap[i] == 0)
                    continue;
                int v = edge[i];
                if(depth[v] != depth[u] + 1) {
                    continue;
                }
                int res = dfs(v, min(cap[i], dist));
                cap[i] -= res;
                cap[^ 1] += res;
                //printf("cap[%d]:%d ",t, cap[t]);
                dist -= res;
                flow += res;
                Nxt[/ 2] = v / 2;
            }
            return flow;
        }

        int maxflow() {
            int ans = 0;
            while(bfs()) {
                ans += dfs(s, inf);
            }
            return ans;
        }
    } dinic;

    int main()
    {
        //freopen("data.txt", "r", stdin);
        read(n);
        dinic.init();
        s = 0, t = 1e5 + 7;
        int balls = 0, coll = 0;
        while(coll <= n) {
            ++balls;
            dinic.BuildGraph(s, balls * 2, 1);
            dinic.BuildGraph(balls * 2 + 1, t, 1);
            for ( int i = sqrt(balls) + 1; i * i < (balls * 2); ++) {
                dinic.BuildGraph((* i - balls) * 2, balls * 2 + 1, 1);
            }
            int maxflow = dinic.maxflow();
            if(maxflow == 0) {
                ++coll;
                Pre[coll] = balls;
            }
        }
        printf("%d ",balls - 1);
        for ( int i = 1; i <= n; ++) {
            if(!vis[Pre[i]]) {
                for ( int u = Pre[i]; u && u != (/ 2); u = Nxt[u] ) {
                    vis[u] = true;
                    printf("%d ",u);
                }
                puts("");
            }
        }
        return 0;
    }
  • 相关阅读:
    国内最火的3款前端开发框架
    Cordova是做什么的
    老师你好。使用cordova生成的hellowold 的安卓5.0版本太高。怎么才可以生成4.4的呢?
    一个类似bootstrap的foundation
    role在标签中的作用是什么?
    如何做到根据不同的进度用不同的颜色显示整个进度条
    wall 和panel有啥区别
    git ignore
    eclipse js 引用跳转
    计划
  • 原文地址:https://www.cnblogs.com/orangeko/p/12770316.html
Copyright © 2011-2022 走看看