最长不下降子序列问题 网络流24题
Posted orangeko
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最长不下降子序列问题 网络流24题相关的知识,希望对你有一定的参考价值。
输入输出样例
输入 #1
4 3 6 2 5
输出 #1
View Code
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 }
#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(T &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 (; (c < ‘0‘ || c > ‘9‘) && c != ‘-‘; c = getc()) {
assert(~c);
}
if (c == ‘-‘) {
pos = false;
c = getc();
}
for (; c >= ‘0‘ && c <= ‘9‘; c = getc()) {
ret = (ret << 3) + (ret << 1) + (c ^ 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(u == 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[i ^ 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(n == 1) {
printf("1
1
1
");
return 0;
}
for ( int i = 1; i <= n; ++i ) {
read(a[i]);
f[i] = 1;
}
int len = 1;
for ( int i = 2; i <= n; ++i ) {
for ( int j = 1; j < i; ++j ) {
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; ++i ) {
if(f[i] == 1) {
dinic.BuildGraph(s, i, 1);
}
if(f[i] == len) {
dinic.BuildGraph(i + n, t, 1);
}
dinic.BuildGraph(i, i + n, 1);
}
for ( int i = 1; i <= n; ++i ) {
for ( int j = i + 1; j <= n; ++j ) {
if(a[j] >= a[i]) {
if(f[i] == f[j] - 1) {
dinic.BuildGraph(i + 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(n * 2, t, inf); dinic.BuildGraph(n, n * 2, inf);
}
ans += dinic.maxflow();
cout << ans << endl;
return 0;
}
以上是关于最长不下降子序列问题 网络流24题的主要内容,如果未能解决你的问题,请参考以下文章