【[USACO06FEB]稳定奶牛分配Steady Cow Assignment】最大流
为什么luogu标签是前缀和贪心和线段树,,,为什么,,,这里是SAP最大流做法
刚学SAP,蒟蒻默默%%%dalao们。
两层的枚举:
第一层:首先二分本题答案(很小,也可以直接枚举)
第二层:然后再套一个枚举,枚举选择哪几个等级。
建图:考虑将所有的牛棚与汇点连边,容量为牛棚容量。再将每一只牛与牛棚连边,容量为1,再将源点与每一只牛连边,容量为1,这样就把一道题转化为了最大流问题了。最后只要汇点爬出最大流为牛的总数就搞定。
于是 就这样一道题 搞定了!
#include<stdio.h>
#include<bits/stdc++.h>
const int inf = 0x3f3f3f3f;
using namespace std;
int n,m;
int dis[205],cnt[10005],v[205][205];
queue<int>q; bool rd[205];
void spfa(int x)
{
for(int i=1;i<=m;i++) dis[i]=inf;
dis[x]=0; q.push(x);
while(q.size())
{
x=q.front(); q.pop(); rd[x]=0;
for(int i=1;i<=m;i++)
{
if(i==x) continue;
if(v[i][x]&&dis[i]>dis[x]+1)
{
dis[i]=dis[x]+1;
if(!rd[i])
{
rd[i]=1;
q.push(i);
}
}
}
}
}
int dfs(int x,int flow)
{
int y,tmp,delta;
if(x==m) return flow;
delta=0;
for(y=1;y<=m;y++)
if(v[x][y]>0&&dis[x]==dis[y]+1)
{
tmp=dfs(y,min(flow-delta,v[x][y]));
delta+=tmp;
v[x][y]-=tmp;
v[y][x]+=tmp;
if(delta==flow||dis[1]>=m) return delta;
}
if(dis[1]>=m) return delta;
cnt[dis[x]]--;
if(!cnt[dis[x]]) dis[1]=m;
dis[x]++;
cnt[dis[x]]++;
return delta;
}
int main()
{
scanf("%d%d",&n,&m);
int x,y,z;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&x,&y,&z);
v[x][y]+=z;
}
// spfa(m);
int ans=0;
while(dis[1]<m)
{
int flow=dfs(1,inf);
ans+=flow;
}
printf("%d",ans);
}

浙公网安备 33010602011771号