【loj】#6005. 「网络流 24 题」最长递增子序列(dp+最大流)
2017-07-19 16:49
316 查看
记录一个菜逼的成长。。
题目链接
网络流最重要的就是建边。
转化成二分图建边。
题目链接
网络流最重要的就是建边。
转化成二分图建边。
#include <bits/stdc++.h> using namespace std; #define ALL(v) (v).begin(),(v).end() #define cl(a,b) memset(a,b,sizeof(a)) #define clr clear() #define pb push_back #define mp make_pair #define fi first #define se second typedef long long LL; typedef pair<int,int> PII; const int INF = 0x3f3f3f3f; const int MAX_V = 1000 + 10; struct edge{ int to,cap,rev,flow; edge(){} edge(int _to,int _cap,int _rev,int _flow):to(_to),cap(_cap),rev(_rev),flow(_flow){} }; vector<edge>G[MAX_V]; int level[MAX_V]; int iter[MAX_V]; void add(int from,int to,int cap,int flow = 0) { G[from].push_back(edge(to,cap,G[to].size(),0)); G[to].push_back(edge(from,0,G[from].size()-1,0)); } void bfs(int s) { memset(level,-1,sizeof(level)); queue<int>que; level[s] = 0; que.push(s); while(!que.empty()){ int f = que.front(); que.pop(); for( int i = 0; i < G[f].size(); i++ ){ edge &e = G[f][i]; if(e.cap > 0 && level[e.to] == -1){ level[e.to] = level[f] + 1; que.push(e.to); } } } } int dfs(int v,int t,int f) { if(v == t)return f; for( int &i = iter[v]; i < G[v].size(); i++ ){ edge &e = G[v][i]; if(e.cap > 0 && level[v] < level[e.to]){ int d = dfs(e.to,t,min(e.cap,f)); if(d > 0){ e.cap -= d;e.flow += d; G[e.to][e.rev].cap += d; return d; } } } return 0; } int max_flow(int s,int t) { int flow = 0; for(;;){ bfs(s); if(level[t] == -1)return flow; memset(iter,0,sizeof(iter)); int f; while((f = dfs(s,t,INF)) > 0) flow += f; } } int s,t,n; int a[MAX_V],dp[MAX_V],f[MAX_V]; int LIS(int *a,int n,int *dp) { int ret = 0; for( int i = 1; i <= n; i++ )dp[i] = INF; for( int i = 1; i <= n; i++ ){ int p = upper_bound(dp+1,dp+1+n,a[i]) - dp; dp[p] = a[i]; f[i] = p; ret = max(ret,p); } return ret; } void solve1(int lis) { for( int i = 1; i <= n; i++ ){ if(f[i] == 1)add(s,i,1); add(i,i+n,1); if(f[i] == lis)add(i+n,t,1); for( int j = 1; j < i; j++ ){ if(a[j] <= a[i] && f[j] + 1 == f[i])add(j+n,i,1); } } printf("%d\n",max_flow(s,t)); } void solve2(int lis) { for( int i = s; i <= t; i++ )G[i].clr; for( int i = 1; i <= n; i++ ){ if(i == 1 || i == n){ if(f[i] == 1)add(s,i,INF); add(i,i+n,INF); if(f[i] == lis)add(i+n,t,INF); } else { if(f[i] == 1)add(s,i,1); add(i,i+n,1); if(f[i] == lis)add(i+n,t,1); } for( int j = 1; j < i; j++ ) if(a[j] <= a[i] && f[j] + 1 == f[i])add(j+n,i,1); } printf("%d\n",max_flow(s,t)); } int main() { scanf("%d",&n); s = 0,t = n + n + 1; for( int i = 1; i <= n; i++ ){ scanf("%d",a+i); } int lis = LIS(a,n,dp); cout<<lis<<endl; if(lis == 1){ printf("%d\n%d\n",n,n); return 0; } solve1(lis); solve2(lis); return 0; }
相关文章推荐
- loj6005「网络流 24 题」最长递增子序列(dp+最大流)
- Libre 6005 「网络流 24 题」最长递增子序列 / Luogu 2766 最长递增子序列问题(网络流,最大流)
- 「网络流 24 题」最长递增子序列
- LOJ 「网络流 24 题」太空飞行计划(最大权闭合子图)
- [网络流24题] 最长递增子序列 (最多不相交路径---网络最大流)
- 线性规划与网络流24——最长递增子序列问题
- 【网络流24题】 No.6 最长不减子序列问题 (最大流)[模型:最多不相交路径]
- 【loj】#6007. 「网络流 24 题」方格取数(二分图最大点权独立集)
- 【网络流24题】最长不下降子序列(最大流,动态规划)
- loj6005「网络流 24 题」最长递增子序列
- loj #6004. 「网络流 24 题」圆桌聚餐(最大流)
- 【loj】#6009. 「网络流 24 题」软件补丁(状态压缩+最短路)
- 【网络流24题】星际转移问题(最大流)
- loj 6006「网络流 24 题」试题库
- 网络流24题 飞行员配对方案问题___最大流
- 【网络流24题】深海机器人(最大费用流)
- 【网络流24题】最长不下降子序列问题
- 【loj】#6000. 「网络流 24 题」搭配飞行员(二分图匹配)
- loj6004「网络流 24 题」圆桌聚餐(最大流)
- 【loj】#6011. 「网络流 24 题」运输问题(最小费用流)