poj 2135 Farm Tour--最小费用最大流--邻接表--构图的时候注意退边--以及退边的算法

/*
题意:n个地点有m条路相连,从1走到n再回来,不走重复的路(这题居然认为,同一条路,按不同的方向走算是走不重复的路)

最小费用最大流

因为要来回,素以相当于找两条1~n的最短路
s~1 流量2 费用0
n~t 流量2 费用0

是每条无向边都拆分成两条有向边
把有向边分别加到图里(还有他的退边,反费用,流量0)
退边和他的反向边的表示是一样的,但是费用和流量是不一样的,所以不可以用邻接矩阵,只能用邻接表了

*/
#include<iostream>
#include<queue>
using namespace std;
const int inf = 0x7fffffff;
const int en = 40010;
const int vn = 1005;
int n,m,mincost,s,t;
int pre[vn],vis[vn],dist[vn];//求最短路径的时候用到的   pre保存流向他的那个边的编号  vis访问标志  dist距离
struct edge//边
{
	int u[en],v[en],f[en],c[en],head[en],yong,next[en];//边的前端和后端 流量 费用 邻接表的头 分配记录 下一条边
	edge()//初始化
	{
		clear();
	}
	void clear()//清除  除  head外  其他的都是主动写入的故不用清除
	{
		yong=1;  
        memset(head,0,sizeof(head));  
	}
	void adde(int uu,int ww,int cost,int flow)//加一条边   加他自己和他的退边
	{
		add(uu,ww,cost,flow);
		add(ww,uu,-cost,0);
	}
	void add(int uu,int ww,int cost,int flow)  //加边
    {  
		u[yong]=uu;
        v[yong]=ww;  
		f[yong]=flow;
		c[yong]=cost;
        next[yong]=head[uu];  
        head[uu]=yong;  
        yong++;  
    }  
}e;
int min(int a,int b)
{
	return a<b?a:b;
}
int spfa()//求最短路径
{
	int i,u,v,p;
	memset(vis,0,sizeof(vis));
	memset(pre,0,sizeof(dist));
	queue<int>q;
	q.push(s);
	vis[s]=1;
	for(i=1;i<=t;++i)
		dist[i]=inf;
	dist[s]=0;
	while(!q.empty())
	{
		u=q.front();
		for(p=e.head[u];p;p=e.next[p])
		{
			v=e.v[p];
			if(e.f[p]&&dist[v]>dist[u]+e.c[p])
			{
				dist[v]=dist[u]+e.c[p];
				pre[v]=p;//记录流向v的那条边的编号  方便后面压入流
				if(!vis[v])
				{
					q.push(v);
					vis[v]=1;
				}
			}
		}
		q.pop();
		vis[u]=0;
	}
	if(dist[t]==inf)
		return 0;
	return 1;
}
void addf()//压入流
{
    
	int i,j; 
	i=pre[t];
	while(i!=0)
	{
		if(i%2)//求边i的退边  之前看别人的代码,直接用了  i^1  结果老是错   人家是从 0 开始用的  我是从1开始用的  所以这里处理一下
			j=i+1;
		else j=i-1;
		e.f[i]--;
		e.f[j]++;
		mincost+=e.c[i];
		i=pre[e.u[i]];
		
	}
	return;    
}
int main()
{
	int i,u,v,c;
	cin>>n>>m;
	mincost=0;
	s=0;
	t=n+1;
	for(i=1;i<=m;++i)
	{
		cin>>u>>v>>c;
		e.adde(u,v,c,1);
		e.adde(v,u,c,1);
	}
	e.adde(s,1,0,2);
	e.adde(n,t,0,2);
	
	while(spfa())	
		addf();
	
	cout<<mincost<<endl;
	return 0;
}

你可能感兴趣的:(c,算法,struct)