P1344-[USACO4.4]追查坏牛奶Pollutant Control【网络流,最小割】

版权声明:原创,未经作者允许禁止转载 https://blog.csdn.net/Mr_wuyongcong/article/details/89518515

正题

题目链接:https://www.luogu.org/problemnew/show/P1344


题目大意

要求1不能到n点需要去掉的边的权值之和最小,在这样的情况下求最少去掉的边。


解题思路

对于每条边的边权分为两部分一个是权值,一个是割掉的数量,然后前者比后者优先。

那么对于每个权值 w w ,就定义为 w E + 1 ( E > n ) w*E+1(E>n)

这样就分为了 w / E w/E w % E w\%E 两部分


c o d e code

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
const ll N=320,M=10010,inf=1e18,cs=2333;
struct node{
	ll to,next,w;
}a[M*2];
ll tot=1,n,s,t,m,ans;
ll dep[N],ls[N];
queue<int> q;
void addl(ll x,ll y,ll w)
{
	a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=w;
	a[++tot].to=x;a[tot].next=ls[y];ls[y]=tot;a[tot].w=0;
}
bool bfs()
{
	memset(dep,0,sizeof(dep));
	while(!q.empty()) q.pop();
	q.push(s);dep[s]=1;
	while(!q.empty())
	{
		ll x=q.front();q.pop();
		for(ll i=ls[x];i;i=a[i].next)
		{
			ll y=a[i].to;
			if(!dep[y]&&a[i].w){
				dep[y]=dep[x]+1;
				if(y==t) return true;
				q.push(y);
			}
		}
	}
	return false;
}
ll dinic(ll x,ll flow)
{
	ll rest=0,k;
	if(x==t) return flow;
	for(ll i=ls[x];i;i=a[i].next)
	{
		ll y=a[i].to;
		if(dep[x]+1==dep[y]&&a[i].w)
		{
			rest+=(k=dinic(y,min(a[i].w,flow-rest)));
			a[i].w-=k;a[i^1].w+=k;
			if(rest==flow) return flow;
		}
	}
	if(!rest) dep[x]=0;
	return rest;
}
void netflow()
{
	while(bfs())
	  ans+=dinic(s,inf);
}
int main()
{
	scanf("%lld%lld",&n,&m);
	s=1;t=n;
	for(ll i=1;i<=m;i++)
	{
		ll x,y,w;
		scanf("%lld%lld%lld",&x,&y,&w);
		w=w*cs+1;addl(x,y,w);
	}
	netflow(); 
	printf("%lld %lld",ans/cs,ans%cs);
}

猜你喜欢

转载自blog.csdn.net/Mr_wuyongcong/article/details/89518515
今日推荐