题目描述 Description
假设以最美观的方式布置花店的橱窗,有F束花,V个花瓶,我们用美学值(一个整数)表示每束花放入每个花瓶所产生的美学效果。为了取得最佳的美学效果,必须使花的摆放取得最大的美学值。
输入描述 Input Description
第一行为两个整数F,V(F<=V<=100)
接下来F行每行V个整数,第i行第j个数表示第i束花放入第j个花瓶的美学值。
输出描述 Output Description
一个整数,即最大美学值。
样例输入 Sample Input
2 2
10 0
5 2
样例输出 Sample Output
12
数据范围及提示 Data Size & Hint
dinic改完之后……
不加当前弧优化会RE…爆栈……卧槽
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int SZ=50010;
const int INF=1000000000;
int head[SZ],nxt[SZ],tot=1;
struct edge{
int t,d,c;
}l[SZ];
void build(int f,int t,int d,int c)
{
l[++tot].t=t;
l[tot].d=d;
l[tot].c=c;
nxt[tot]=head[f];
head[f]=tot;
}
int s,e,n;
queue<int> q;
bool use[SZ];
int dist[SZ];
bool spfa()
{
for(int i=1;i<=n;i++) dist[i]=INF;
use[s]=1;
q.push(s);
dist[s]=0;
while(q.size())
{
int f=q.front(); q.pop();
use[f]=0;
for(int i=head[f];i;i=nxt[i])
{
int v=l[i].t;
if(l[i].c && dist[v] > dist[f] + l[i].d)
{
dist[v] = dist[f] + l[i].d;
if(!use[v])
{
use[v]=1;
q.push(v);
}
}
}
}
if(dist[e]==INF) return false;
return true;
}
bool vis[SZ];
int dfs(int u,int flow,int &cost)
{
if(flow==0 || u==e) return flow;
int ans=0;
for(int i=head[u];i;i=nxt[i])
if(!vis[i])
{
int v=l[i].t;
if(l[i].c && dist[v] == dist[u] + l[i].d)
{
vis[i]=1;
int f=dfs(v,min(flow,l[i].c),cost);
if(f > 0)
{
l[i].c -= f;
cost += l[i].d;
l[i^1].c += f;
ans += f;
flow -= f;
if(flow == 0) break;
}
vis[i]=0;
}
}
if(ans == 0) dist[u] = INF;
return ans;
}
int dinic()
{
int cost=0,flow=0;
while(spfa())
{
int tmp=dfs(s,INF,cost);
if(tmp == 0) break;
flow+=tmp;
memset(vis,0,sizeof(vis));
}
return cost;
}
int main()
{
int aa,bb;
scanf("%d%d",&aa,&bb);
n=aa+bb;
for(int i=1;i<=aa;i++)
{
for(int j=aa+1;j<=n;j++)
{
int x;
scanf("%d",&x);
build(i,j,-x,1); build(j,i,x,0);
}
}
s=++n; e=++n;
for(int i=1;i<=aa;i++) build(s,i,0,1),build(i,s,0,0);
for(int i=aa+1;i<=aa+bb;i++) build(i,e,0,1),build(e,i,0,0);
printf("%d\n",-dinic());
return 0;
}
/*
3 5
7 23 -5 -24 16
5 21 -4 10 23
-21 5 -4 -20 20
*/