题意:

给一个有向无环带权图,每条路径上最多只能割一条边,最后使1到n无路径,问最小割边边权和是多少。

题意很清楚,但是这道题的题解其实是只适用于很少的情况的

我们考虑的做法是网络流最小割

对于所有边的反向边,流量均为inf

那么如果具体分析原因其实是这条路径割上游,那条路径割下游,然而可以走这条路径的上游和那条路径的下游,如何避免?

考虑到那条路径的上游和这条路径的下游是没有割的,中间的边如果可以反着走那么就可以很好的避免这种情况的发生

所以如果反向边是inf就可以很好的解决这个问题了

但是这样子想未必太过美好了一点,例如:

如果在网络流的图中有一条边是反向建的,那么正向的流量就是inf,导致答案与正确答案不符

无论如何,这道题的思路还是很好的,下贴代码

#include<bits/stdc++.h>
using namespace std;
const int inf=0x7fffffff;
int tot=1,w[2005],remain[2005],to[2005],nxt[2005];
int head[305],depth[305],hh[305];
int n,m,shu1,shu2,shu3,ans;
queue <int> que;
int minn(int x,int y)
{
	if(x<y) return x;
	return y;
}
void add(int x,int y,int z)
{
	to[++tot]=y;
	nxt[tot]=head[x];
	head[x]=tot;
	remain[tot]=z;
}
bool bfs()
{
	que.push(1);
	memset(depth,0,sizeof(depth));
	depth[1]=1;
	while(!que.empty())
	{
		int x=que.front();
		que.pop();
		for(int i=head[x];i;i=nxt[i])
		{
			int y=to[i];
			if(!remain[i]||depth[y]) continue;
			depth[y]=depth[x]+1;
			que.push(y);
		}
	}
	return depth[n];
}
int dfs(int x,int delta)
{
	if(x==n) return delta;
	int sum=0;
	for(int &i=hh[x];i&&delta;i=nxt[i])
	{
		int y=to[i];
		if(depth[y]!=depth[x]+1||!remain[i]) continue;
		int flow=minn(remain[i],dfs(y,delta));
		remain[i]-=flow;
		remain[i^1]+=flow;
		sum+=flow;
		delta-=flow;
	}
	return sum;
}
int main()
{
 	freopen("mer.in","r",stdin);
	freopen("mer.out","w",stdout);
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&shu1,&shu2,&shu3);
		add(shu1,shu2,shu3);
		add(shu2,shu1,inf/3);
	}
	while(bfs())
	{
		for(int i=1;i<=n;i++)
		hh[i]=head[i];
		ans+=dfs(1,inf);
	}
	cout<<ans;
	return 0;
}