# 【BZOJ-4261】建设游乐场 最大费用最大流

## 4261: 建设游乐场

Time Limit: 50 Sec  Memory Limit: 256 MB
Submit: 21  Solved: 8
[Submit][Status][Discuss]

## Description

（每张图表示一块平原格子，图内网格线为辅助线，无实际意义。）

3 3
1 1 1
1 0 0
1 0 0
48 94 1
78 78 81
1 12 60

231

## HINT

N<=150,M<=30,Vi,j<=100

## Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9')  {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}

#define MAXN 30010
#define INF 0x7fffffff

int N,M,mp[200][50],val[200][50],sum,tot;

struct EdgeNode{
int next,to,cap,cost;
}edge[500010];

int Cost,S,T,dis[MAXN],mark[MAXN];
queue<int>q;
inline bool spfa()
{
for (int i=S; i<=T; i++) dis[i]=-INF,mark[i]=0;
queue<int>q;
q.push(S); dis[S]=0; mark[S]=1;
while (!q.empty()) {
int now=q.front(); q.pop(); mark[now]=0;
if (edge[i].cap && dis[edge[i].to]<dis[now]+edge[i].cost) {
dis[edge[i].to]=dis[now]+edge[i].cost;
if (!mark[edge[i].to]) q.push(edge[i].to),mark[edge[i].to]=1;
}
}
return dis[T]!=-INF;
}

inline int dfs(int loc,int low)
{
mark[loc]=1;
if (loc==T) return low;
int used=0,w;
if (edge[i].cap && !mark[edge[i].to] && dis[edge[i].to]==dis[loc]+edge[i].cost) {
w=dfs(edge[i].to,min(edge[i].cap,low-used));
edge[i].cap-=w; edge[i^1].cap+=w; used+=w; Cost+=w*edge[i].cost;
if (low==used) return used;
}
return used;
}

inline int zkw()
{
int re=0;
while (spfa()) {
mark[T]=1;
while (mark[T]) {
for (int i=S; i<=T; i++) mark[i]=0;
re+=dfs(S,INF);
}
}
return re;
}

int col[200][50],id[200][50][3],ID,dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
//id 0 主点 id 1 竖方向 id 3 横方向
inline bool Check(int x,int y) {return x>=1&&x<=N&&y>=1&&y<=M;}
int main()
{
for (int i=1; i<=N; i++)
for (int j=1; j<=M; j++)
for (int i=1; i<=N; i++)
for (int j=1; j<=M; j++)

for (int i=1; i<=N; i++)
for (int j=1; j<=M; j++)
for (int k=0; k<=2; k++) id[i][j][k]=++ID;

S=0; T=++ID;

for (int i=1; i<=N; i++)
for (int j=1; j<=M; j++)
if (!mp[i][j]) {
if (col[i][j]) {
InsertEdge(S,id[i][j][0],2,0);
InsertEdge(id[i][j][0],id[i][j][1],1,val[i][j]);
InsertEdge(id[i][j][0],id[i][j][1],1,0);
InsertEdge(id[i][j][0],id[i][j][2],1,val[i][j]);
InsertEdge(id[i][j][0],id[i][j][2],1,0);
} else {
tot+=2;
InsertEdge(id[i][j][0],T,2,0);
InsertEdge(id[i][j][1],id[i][j][0],1,val[i][j]);
InsertEdge(id[i][j][1],id[i][j][0],1,0);
InsertEdge(id[i][j][2],id[i][j][0],1,val[i][j]);
InsertEdge(id[i][j][2],id[i][j][0],1,0);
}
}

for (int i=1; i<=N; i++)
for (int j=1; j<=M; j++)
if (!mp[i][j] && col[i][j])
for (int k=0; k<=3; k++) {
int tx=i+dx[k],ty=j+dy[k];
if (Check(tx,ty) && !mp[tx][ty])
if (k==0 || k==2)
InsertEdge(id[i][j][1],id[tx][ty][1],1,0);
else
InsertEdge(id[i][j][2],id[tx][ty][2],1,0);
}

int flow=zkw();

if (flow<tot) return puts("-1"),0;

printf("%d\n",Cost-sum);

return 0;
}


——It's a lonely path. Don't make it any lonelier than it has to be.
posted @ 2017-02-23 17:49  DaD3zZ  阅读(522)  评论(1编辑  收藏  举报