萌新刚学 OI,再次求助挂掉的网络流

P2766 最长不下降子序列问题

SIXIANG32 @ 2021-06-07 22:09:01

#include <iostream> 
#include <cstring>
#include <queue>
#define MAXN 300000
#define INF 0x7f7f7f7f
#define QWQ cout << "QWQ" << endl;
using namespace std;
int tot = 1, n, m, s, t;
int max(int x, int y) {return ((x > y) ? (x) : (y));}
int min(int x, int y) {return ((x < y) ? (x) : (y));}
struct node {
    int to, val, next;
} gra[MAXN * 2 + 10];
int head[MAXN + 10], fa[MAXN + 10];
void link(int x, int y, int z) {
    gra[++tot].to = y, gra[tot].val = z, gra[tot].next = head[x], head[x] = tot;
    gra[++tot].to = x, gra[tot].val = 0, gra[tot].next = head[y], head[y] = tot;
}
int dis[MAXN + 10], f[MAXN + 10], Now[MAXN + 10], a[MAXN + 10];
bool vis[MAXN + 10];
bool qwq[MAXN + 10];
bool bfs() {
    memset(dis, 0, sizeof(dis));
    queue <int> que;
    que.push(s), dis[s] = 1, Now[s] = head[s];
    while(!que.empty()) {
        int fr = que.front(); que.pop();
        for(int p = head[fr]; p; p = gra[p].next) {
            int v = gra[p].to, w = gra[p].val;
            if(w && !dis[v]) {
                que.push(v);
                Now[v] = head[v];
                dis[v] = dis[fr] + 1;
                if(v == t) return 1;
            }
        }
    }
    return 0;
}
int Dinic(int u, int over) {
    if(u == t) return over;
    int res = over;
    for(int p = Now[u]; p && res; p = gra[p].next) {
        int v = gra[p].to, w = gra[p].val;
        Now[u] = p;
        if(w && dis[v] == dis[u] + 1) {
            int k = Dinic(v, min(res, w));
            if(!k) dis[v] = 0x7f7f7f7f;
            if(u != s) vis[v - n] = 1;
            gra[p].val -= k;
            gra[p ^ 1].val += k;
            res -= k;
        }
    }
    return over - res;
}
int Max_Flow() {
    int rest = 0;
    while(bfs()) {
        rest += Dinic(s, INF);
    }
    return rest;
}
int solve_1(int len) {
    for(int p = 1; p <= len; p++) f[p] = 1;
    for(int p = 1; p <= len; p++)
        for(int i = 1; i < p; i++)
            if(a[p] >= a[i])
                f[p] = max(f[p], f[i] + 1);
    int maxn = 0;
    for(int p = 1; p <= len; p++)
        maxn = max(maxn, f[p]);
    return maxn;
}
void solve_2(int len, int ml) {
    for(int p = 1; p <= len; p++) {
        if(f[p] == 1) link(s, p, 1);
        if(f[p] == ml) link(p + len, t, 1);
        link(p, p + len, 1);
    }
    for(int p = 1; p <= len; p++)
        for(int i = 1; i < p; i++)
            if(f[i] + 1 == f[p] && a[p] >= a[i])
                link(i + len, p, 1);
    int qwq = Max_Flow();
    cout << qwq << endl;
}
void solve_3(int len, int ml) {
    link(1, 1 + len, INF), link(s, 1, INF);
    if(f[len] == ml) link(len, len + len, INF), link(len + len, t, INF);
    cout << Max_Flow() << endl;
}
int main() {
    int n;
    cin >> n, s = n * 2 + 1, t = n * 2 + 2;
    for(int p = 1; p <= n; p++)
        cin >> a[p];
    int ml = solve_1(n);
    cout << ml << endl;
    solve_2(n, ml);
    solve_3(n, ml); 
}

我也不知道第三问怎么会挂啊/kk
检查了很多次,没毛病啊/kk 求助/kel


by hjl_AK_IOI @ 2021-06-07 22:29:47

这位老兄,做人且低调
我才不会告诉你我看不懂


by SIXIANG32 @ 2021-06-08 12:42:45

@tgyyds ?
我求助网络流怎么不低调了?/yiw
@zhangqs zqs 帮我康康/kel


by SIXIANG32 @ 2021-06-08 13:11:34

重建图就好了,此贴终。。。


by S0CRiA @ 2022-01-02 16:24:37

@Little_Sealx 其实是因为你在跑网络流的时候会修改流的权值,导致求解第三问的时候的流其实是第二问求过后的残量网络。

还有个解决方法是把第二问答案和第三问错误答案加上后就是第三问正确答案。


by SIXIANG32 @ 2022-01-02 17:26:32

@_zyINF 谢谢巨佬 qwq


|