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

Posted orangeko

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最长不下降子序列问题 网络流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;
}

以上是关于最长不下降子序列问题 网络流24题的主要内容,如果未能解决你的问题,请参考以下文章

洛谷2766:[网络流24题]最长不下降子序列问题——题解

P2766 [网络流24题]最长不下降子序列问题

网络流24题最长不下降子序列(最大流,动态规划)

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

[网络流24题] 最长递增子序列

网络流24题之最长不下降子序列问题