网络流 模板题
参考
http://blog.youkuaiyun.com/sdj222555/article/details/7797257
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <sstream>
using namespace std;
#define ll long long
const int MAXN = 105;
const int MAXM = 400010;
const int INF = 0x3f3f3f3f;
struct Edge{
int st , to , next, cap , flow;
}edge[MAXN<<3];
int tol , head[MAXN<<1] , gap[MAXN<<1] , dep[MAXN<<1] , cur[MAXN<<1];
void init(){
tol = 0;
memset(head , -1 , sizeof(head));
}
void add_edge(int u , int v , int w , int rw=0){
edge[tol].st = u , edge[tol].to=v , edge[tol].cap = w , edge[tol].flow=0;
edge[tol].next = head[u] , head[u] = tol++;
edge[tol].st = v , edge[tol].to = u , edge[tol].cap = rw , edge[tol].flow=0;
edge[tol].next = head[v] , head[v] = tol++;
}
int Q[MAXN];
void BFS(int start , int end)
{
memset(dep , -1 , sizeof(dep));
memset(gap , 0 , sizeof(gap));
gap[0] = 1;
int front = 0 , rear = 0;
dep[end] = 0;
Q[rear++] = end;
while(front != rear){
int u = Q[front++];
for(int i=head[u] ; i!=-1 ; i=edge[i].next){
int v = edge[i].to ;
if(dep[v]!=-1) continue;
Q[rear++] = v;
dep[v] = dep[u] + 1;
gap[dep[v]]++;
}
}
}
int S[MAXN<<1];
int isap(int start , int end , int N){
BFS(start , end);
memcpy(cur , head , sizeof(head));
int top=0;
int u=start;
int ans = 0;
while(dep[start]<N)
{
if(u == end){
int Min = INF;
int inser;
for(int i=0 ; i<top ; i++)
if(Min>edge[S[i]].cap-edge[S[i]].flow){
Min = edge[S[i]].cap-edge[S[i]].flow;
inser = i;
}
for(int i=0 ; i<top ; i++){
edge[S[i]].flow+=Min;
edge[S[i]^1].flow-=Min;
}
ans+=Min;
top = inser;
u = edge[S[top]^1].to;
continue;
}
bool flag = false;
int v ;
for(int i=cur[u] ; i!=-1 ; i=edge[i].next){
v = edge[i].to;
if(edge[i].cap-edge[i].flow && dep[v]+1==dep[u]){
flag = true;
cur[u] = i;
break;
}
}
if(flag){
S[top++] = cur[u];
u = v;
continue;
}
int Min = N;
for(int i=head[u] ; i!=-1 ; i=edge[i].next){
if(edge[i].cap-edge[i].flow && dep[edge[i].to]<Min){
Min = dep[edge[i].to];
cur[u] = i;
}
}
gap[dep[u]]--;
if(!gap[dep[u]]) return ans;
dep[u] = Min+1;
gap[dep[u]]++;
if(u != start) u = edge[S[--top]^1].to;
}
return ans;
}
int st, en, n;
int fg[MAXN][MAXN],g[MAXN],m[MAXN][MAXN];
void build(int k ){
init();
for(int i = 1; i <= n; i++){
add_edge(i,en,g[i]);
for(int j = i+1 ; j <= n; j++){
add_edge(st,m[i][j],1);
}
}
memset(fg,0,sizeof(fg));
for(int i = n-k+1; i <= n; i++){
for(int j = i+1; j <= n; j++){
if(g[i] < g[j]){
add_edge(m[i][j],i,1);
fg[i][j] = 1;
}
}
}
for(int i = 1; i <= n; i++){
for(int j = i+1; j <= n; j++){
if(!fg[i][j]){
add_edge(m[i][j],i,1);
add_edge(m[i][j],j,1);
}
}
}
}
void cut(char *s){
int len = strlen(s);
int t = 0;
for(int i = 0; i < len; i++){
if(s[i] >= '0' && s[i] <= '9')
{
t = t * 10 + s[i] - '0';
if(i == len - 1 || s[i + 1] == ' ')
{
g[++n] = t;
t = 0;
}
}
}
}
int main(){
char str[40];
int i,j,t;
scanf("%d",&t);
getchar();
while(t--){
gets(str);
n=0;
cut(str);
int tt = n;
for(int i = 1; i <= n; i++){
for(int j = i+1; j<= n ; j++){
m[j][i] = m[i][j] = ++tt;
}
}
st = 0, en = tt + 1;
int ans = 1;
for(int i = n; i >= 1; i--){
build(i);
int temp = isap(st,en,en);
if(temp == n*(n-1)/2){
ans = i;
break;
}
}
printf("%d\n",ans);
}
return 0;
}