• 最长不下降子序列问题 【网络流24题】


    输入输出样例

    输入 #1
    4
    3 6 2 5
    输出 #1
    2
    2
    3

    思路

      Task1:数据范围很小,暴力出LIS长度就可以了

      Task2:显然是个带限制条件的最小路径覆盖问题

           拆点建图,以该点是否为LIS的起终点为依据判断是否对ST连边

           对所有点肯定要满足该点出点要连下一个点的入点

      Task3:取消对1点和n点的限制,计算出对残量网络的影响

           如果由残量网络,就继续加流直至跑满。

      Note:对 n 为 1 的时候显然需要特判一下。

    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 map<int, int> vis;
     59 
     60 struct DINIC {
     61     int head[maxn << 1], nxt[maxn << 1], edge[maxn << 1], cnt;
     62     int cap[maxn << 1], depth[maxn << 1];
     63 
     64     void init() {
     65         cnt = 1;
     66         memset(head, 0, sizeof(head));
     67         memset(cap, 0, sizeof(cap));
     68         memset(depth, 0, sizeof(depth));
     69         vis.clear();
     70     }
     71 
     72     void BuildGraph(int u, int v, int w) {
     73         ++cnt;
     74         edge[cnt] = v;
     75         nxt[cnt] = head[u];
     76         cap[cnt] = w;
     77         head[u] = cnt;
     78 
     79         ++cnt;
     80         edge[cnt] = u;
     81         nxt[cnt] = head[v];
     82         cap[cnt] = 0;
     83         head[v] = cnt;
     84     }
     85 
     86     queue<int> q;
     87 
     88     bool bfs() {
     89         memset(depth, 0, sizeof(depth));
     90         depth[s] = 1;
     91         q.push(s);
     92         while(!q.empty()) {
     93             int u = q.front();
     94             q.pop();
     95             for ( int i = head[u]; i; i = nxt[i] ) {
     96                 int v = edge[i];
     97                 if(depth[v]) {
     98                     continue;
     99                 }
    100                 if(cap[i]) {
    101                     depth[v] = depth[u] + 1;
    102                     q.push(v);
    103                 }
    104             }
    105         }
    106         return depth[t];
    107     }
    108 
    109     int dfs(int u, int dist) {
    110         if(u == t) {
    111             return dist;
    112         }
    113         int flow = 0;
    114         for ( int i = head[u]; i && dist; i = nxt[i] ) {
    115             if(cap[i] == 0)
    116                 continue;
    117             int v = edge[i];
    118             if(depth[v] != depth[u] + 1) {
    119                 continue;
    120             }
    121             int res = dfs(v, min(cap[i], dist));
    122             cap[i] -= res;
    123             cap[i ^ 1] += res;
    124             //printf("cap[%d]:%d
    ",t, cap[t]);
    125             dist -= res;
    126             flow += res;
    127         }
    128         return flow;
    129     }
    130 
    131     int maxflow() {
    132         int ans = 0;
    133         while(bfs()) {
    134             ans += dfs(s, inf);
    135         }
    136         return ans;
    137     }
    138 } dinic;
    139 
    140 int a[maxn];
    141 int f[maxn];
    142 
    143 int main()
    144 {
    145     //freopen("data.txt", "r", stdin);
    146     read(n);
    147     if(n == 1) {
    148         printf("1
    1
    1
    ");
    149         return 0;
    150     }
    151     for ( int i = 1; i <= n; ++i ) {
    152         read(a[i]);
    153         f[i] = 1;
    154     }
    155     int len = 1;
    156     for ( int i = 2; i <= n; ++i ) {
    157         for ( int j = 1; j < i; ++j ) {
    158             if(a[j] <= a[i]) {
    159                 f[i] = max(f[i], f[j] + 1);
    160             }
    161         }
    162         len = max(len, f[i]);
    163     }
    164     // for ( int i = 1; i <= n; ++i ) {
    165     //     printf("f[%d]:%d
    ",i, f[i]);
    166     // }
    167     cout << len << endl;
    168     dinic.init();
    169     s = 0, t = maxn;
    170     for ( int i = 1; i <= n; ++i ) {
    171         if(f[i] == 1) {
    172             dinic.BuildGraph(s, i, 1);
    173         }
    174         if(f[i] == len) {
    175             dinic.BuildGraph(i + n, t, 1);
    176         }
    177         dinic.BuildGraph(i, i + n, 1);
    178     }
    179     for ( int i = 1; i <= n; ++i ) {
    180         for ( int j = i + 1; j <= n; ++j ) {
    181             if(a[j] >= a[i]) {
    182                 if(f[i] == f[j] - 1) {
    183                     dinic.BuildGraph(i + n, j, 1);
    184                 }
    185             }
    186         }
    187     }
    188     int ans = dinic.maxflow();
    189     cout << ans << endl;
    190     dinic.BuildGraph(s, 1, inf);dinic.BuildGraph(1, 1 + n, inf);
    191     if(f[n] == len) {
    192         dinic.BuildGraph(n * 2, t, inf); dinic.BuildGraph(n, n * 2, inf);
    193     }
    194     ans += dinic.maxflow();
    195     cout << ans << endl;
    196     return 0;
    197 }
    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;
    };

    map<int, int> vis;

    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));
            memset(cap, 0, sizeof(cap));
            memset(depth, 0, sizeof(depth));
            vis.clear();
        }

        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;
            }
            return flow;
        }

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

    int a[maxn];
    int f[maxn];

    int main()
    {
        //freopen("data.txt", "r", stdin);
        read(n);
        if(== 1) {
            printf("1 1 1 ");
            return 0;
        }
        for ( int i = 1; i <= n; ++) {
            read(a[i]);
            f[i] = 1;
        }
        int len = 1;
        for ( int i = 2; i <= n; ++) {
            for ( int j = 1; j < i; ++) {
                if(a[j] <= a[i]) {
                    f[i] = max(f[i], f[j] + 1);
                }
            }
            len = max(len, f[i]);
        }
        // for ( int i = 1; i <= n; ++i ) {
        //     printf("f[%d]:%d ",i, f[i]);
        // }
        cout << len << endl;
        dinic.init();
        s = 0, t = maxn;
        for ( int i = 1; i <= n; ++) {
            if(f[i] == 1) {
                dinic.BuildGraph(s, i, 1);
            }
            if(f[i] == len) {
                dinic.BuildGraph(+ n, t, 1);
            }
            dinic.BuildGraph(i, i + n, 1);
        }
        for ( int i = 1; i <= n; ++) {
            for ( int j = i + 1; j <= n; ++) {
                if(a[j] >= a[i]) {
                    if(f[i] == f[j] - 1) {
                        dinic.BuildGraph(+ n, j, 1);
                    }
                }
            }
        }
        int ans = dinic.maxflow();
        cout << ans << endl;
        dinic.BuildGraph(s, 1, inf);dinic.BuildGraph(1, 1 + n, inf);
        if(f[n] == len) {
            dinic.BuildGraph(* 2, t, inf); dinic.BuildGraph(n, n * 2, inf);
        }
        ans += dinic.maxflow();
        cout << ans << endl;
        return 0;
    }
  • 相关阅读:
    基于Qt的图像处理技术和算法
    项目中使用到的算法
    C++将数组的元素顺序随机打乱
    Windows环境下 RabbitMQ集群配置
    Nginx负载均衡配置
    SQL Server Profiler:使用方法和指标说明
    如何查看IIS并发连接数
    23种设计模式的趣味理解
    C# 开源框架(整理)
    git 简易教程
  • 原文地址:https://www.cnblogs.com/orangeko/p/12772313.html
Copyright © 2020-2023  润新知