——APIO2017何昊天《APIO2017 网络流建模及其应用》
上一题就是那个切糕
// BEGIN CUT HERE
// END CUT HERE
#line 5 "FoxAndCity.cpp"
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <queue>
using namespace std;
const int N=2000010,inf=1<<29;
int n,S,T,cnt,G[50*50],f[55][55],c[55][55];
struct edge{
int t,nx,f;
}E[N];
inline void link(int x,int y,int f){
//cerr<<'\t'<<x<<' '<<y<<' '<<f<<endl;
E[++cnt].t=y; E[cnt].nx=G[x]; E[cnt].f=f; G[x]=cnt;
E[++cnt].t=x; E[cnt].nx=G[y]; E[cnt].f=0; G[y]=cnt;
}
queue<int> Q;
int dis[50*50],cur[50*50];
inline bool bfs(){
while(!Q.empty()) Q.pop();
for(int i=0;i<=T;i++) dis[i]=-1;
Q.push(S); dis[S]=0;
while(!Q.empty()){
int x=Q.front(); Q.pop();
for(int i=G[x];i;i=E[i].nx)
if(E[i].f && dis[E[i].t]==-1){
dis[E[i].t]=dis[x]+1;
if(E[i].t==T) return true;
Q.push(E[i].t);
}
}
return false;
}
int dfs(int x,int f){
if(x==T || !f) return f;
int used=0,w;
for(int &i=cur[x];i;i=E[i].nx)
if(E[i].f && dis[E[i].t]==dis[x]+1){
w=dfs(E[i].t,min(E[i].f,f-used));
E[i].f-=w; E[i^1].f+=w;
if((used+=w)==f) return f;
}
if(!used) dis[x]=-1;
return used;
}
class FoxAndCity{
public:
int minimalCost(vector <string> linked, vector <int> want){
memset(G,0,sizeof(G)); cnt=1; n=linked.size(); int t=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
f[i][j]=linked[i-1][j-1]=='Y';
for(int i=2;i<=n;i++)
for(int j=1;j<=n;j++) c[i][j]=++t;
S=0; T=++t;
link(S,1,0); link(1,T,inf);
for(int i=2;i<=n;i++){
for(int j=1;j<=n;j++){
if(j==1)
link(S,c[i][j],inf);
else
link(c[i][j-1],c[i][j],(j-1-want[i-1])*(j-1-want[i-1]));
}
link(c[i][n],T,inf);
}
for(int i=2;i<=n;i++)
if(f[1][i]) link(c[i][2],1,inf);
for(int i=2;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=i+1;k<=n;k++)
if(f[i][k]){
if(j+1<=n)
link(c[k][j+1],c[i][j],inf);
if(j-2>0)
link(c[i][j-1],c[k][j-2],inf);
}
}
}
int ans=0;
while(bfs()){
for(int i=0;i<=T;i++) cur[i]=G[i];
ans+=dfs(S,inf);
}
return ans;
}
};