网络流24题6

Posted tjucxz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络流24题6相关的知识,希望对你有一定的参考价值。

https://loj.ac/problem/6005

根据以i开始最长的上升子序列分层,每一层连向下一层当且仅当a[i]<=a[j] 且dp[i]=dp[j]+1 这样保证网络流中每一个流量是1的走的都是最长的上升子序列,这样最大流就是答案

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
using namespace std;
const int maxn = 509;
int dp[maxn];
int a[maxn];
int s;
int n;
int head[maxn*3];
int tot = 0;
struct edge{
    int v,nex,w;
}e[maxn*maxn*2];
void addedge(int u,int v,int w){
    e[tot] = (edge){v,head[u],w};
    head[u] = tot++;
    e[tot] = (edge){u,head[v],0};
    head[v] = tot++;
}
int deep[maxn*3];


bool bfs(int S,int T){
    memset(deep,0,sizeof(deep));
    deep[S] = 1;
    queue<int> q;
    q.push(S);
    while (!q.empty()) {
        int now = q.front();
        q.pop();
        for(int i=head[now];i!=-1;i=e[i].nex){
            int v = e[i].v;
            int w = e[i].w;
            if(deep[v]!=0 || w<=0 ) continue;
            deep[v] = deep[now]+1;
            q.push(v);
        }
    }
    return deep[T];
}
int dfs(int now,int T,int maxflow){
    if(now==T) return maxflow;
    int all = 0;
    for(int i=head[now];i!=-1 && all <maxflow;i=e[i].nex){
        int w = e[i].w;
        int v = e[i].v;
        if(deep[v]!=deep[now]+1 || w<=0) continue;
        int tt = dfs(v,T,min(maxflow-all,w));
        e[i].w-=tt;
        e[i^1].w+=tt;
        all+=tt;
    }
    return all;
}
int dinic(int S,int T){
    int ret = 0;
    while (bfs(S,T)) {
        ret+=dfs(S,T,0x3f3f3f3f);
    }
    return ret;
}
void solve1(){
    memset(head,-1,sizeof(head));
    tot = 0;
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            if(a[i]<=a[j]&& dp[i]==dp[j]+1){
                addedge(2*i+1,2*j,1);
            }
        }
    }
    for(int i=1;i<=n;i++){
        addedge(2*i,2*i+1,1);
        if(dp[i]==s)
        addedge(0, 2*i, 1);
        if(dp[i]==1)
        addedge(2*i+1, 1,1);
    }
    int ans = dinic(0,1);
    if(s==1)
        ans= n;
    printf("%d\n",ans);
    
}
void solve2(){
    memset(head,-1,sizeof(head));
    tot = 0;
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            if(a[i]<=a[j]&& dp[i]==dp[j]+1){
                addedge(2*i+1,2*j,1);
            }
        }
    }
    for(int i=1;i<=n;i++){
        addedge(2*i,2*i+1,0x3f3f3f3f);
        if(dp[i]==s)
            addedge(0, 2*i, 0x3f3f3f3f);
        if(dp[i]==1)
            addedge(2*i+1, 1,0x3f3f3f3f);
    }
    int ans = dinic(0,1);
    if(s==1)
        ans = n;
    printf("%d\n",ans);
    
}
int main(int argc, const char * argv[]) {

    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    s = 0;
    for(int i=n;i>=1;i--){
        int t = 0;
        for(int j=i+1;j<=n;j++){
            if(a[i]<=a[j]){
                t = max(t,dp[j]);
            }
        }
        dp[i] = t+1;
        s = max(dp[i],s);
    }
    printf("%d\n",s);
    solve1();
    solve2();
    return 0;
}

  

以上是关于网络流24题6的主要内容,如果未能解决你的问题,请参考以下文章

网络流 24 题 解题报告

网络流 24 题 解题报告

网络流24题

网络流24题-题目总结

网络流24题汇总

cwl的网络流24题练习