对于无向图的最大流:
建边的时候,反向边的容量和正向边是一样的,而不是0;
对于无向图的最小费用流:
建边的时候,一条无向边对应4条边:
①正向边,容量为f,费用为c
②反向边,容量为0,费用为-c
③反向边,容量为f,费用为c
④正向边,容量为0,费用为-c
说白了,就是把无向图看作是有向图,然后像有向图那样一条有向边建两条边,也就变成了一条无向边建四条边
注意:开数组的时候一定要注意开2倍的M和4倍的M,还有spfa中的队列要用循坏队列。
无向图的最大流(hdu.4280)
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int N=100005,M=200005;
int n,m,Te,S,T;
int h[N],e[M],ne[M],flow[M],idx;
void add(int a,int b,int f)
{
flow[idx]=f,e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int dist[N];
int q[N],hh,tt;
bool bfs()
{
memset(dist,0x3f,sizeof dist);
dist[S]=0;
hh=0,tt=-1;
q[++tt]=S;
while(hh<=tt)
{
int x=q[hh++];
for(int i=h[x];~i;i=ne[i])
{
int j=e[i];
if(flow[i]&&dist[j]>dist[x]+1)
{
dist[j]=dist[x]+1;
q[++tt]=j;
}
}
}
return dist[T]<0x3f3f3f3f;
}
int dfs(int u,int fl)
{
if(u==T) return fl;
int res=0;
for(int i=h[u];~i;i=ne[i])
{
int j=e[i];
if(dist[j]==dist[u]+1&&flow[i])
{
int x=dfs(j,min(fl,flow[i]));
fl-=x,res+=x,flow[i]-=x,flow[i^1]+=x;
if(!fl) break;
}
}
if(!res) dist[u]=1<<30;
return res;
}
int maxflow()
{
int res=0;
while(bfs())
{
res+=dfs(S,INT_MAX);
}
return res;
}
int main()
{
cin>>Te;
while(Te--)
{
cin>>n>>m;
memset(h,-1,sizeof h),idx=0;
int minx=INT_MAX,maxx=INT_MIN;
for(int i=1;i<=n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
if(x<minx) S=i,minx=x;
if(x>maxx) T=i,maxx=x;
}
while(m--)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z),add(y,x,z);
}
cout<<maxflow()<<endl;
}
return 0;
}
无向图的费用流(poj2135)
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <climits>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=1010,M=4e4+50;
int n,m,S,T;
int h[N],e[M],ne[M],flow[M],co[M],idx;
void add(int a,int b,int f,int c)
{
flow[idx]=f,co[idx]=c,e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int dist[N],pre[N];
bool st[N];
bool spfa()
{
memset(dist,0x3f,sizeof dist);
memset(pre,-1,sizeof pre);
memset(st,0,sizeof st);
dist[S]=0;
queue<int>q;
q.push(S);
st[S]=true;
while(q.size())
{
int x=q.front();q.pop();
st[x]=false;
for(int i=h[x];~i;i=ne[i])
{
int j=e[i];
if(flow[i]&&dist[j]>dist[x]+co[i])
{
dist[j]=dist[x]+co[i];
pre[j]=i;
if(!st[j]) st[j]=true,q.push(j);
}
}
}
return dist[T]<0x3f3f3f3f;
}
void maxflow(int &ans)
{
while(spfa())
{
int cur=pre[T];
while(cur!=-1)
flow[cur]-=1,flow[cur^1]+=1,cur=pre[e[cur^1]];
ans+=dist[T];
}
}
int main()
{
memset(h,-1,sizeof h);
cin>>n>>m;S=0,T=n;
while(m--)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,1,z),add(y,x,0,-z);
add(y,x,1,z),add(x,y,0,-z);
}
add(S,1,2,0);add(1,S,0,0);
int ans=0;
maxflow(ans);
cout<<ans<<endl;
return 0;
}