最小费用最大流模板:
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
#define LL long long
#define CLEAR(xxx) memset(xxx,0,sizeof(xxx))
using namespace std;
const int inf=1e9;
const int maxn=1000+5;
int N,n,m,maxflow,mincost,last[maxn];
inline void _read(int &x){
char ch=getchar(); bool mark=false;
for(;!isdigit(ch);ch=getchar())if(ch=='-')mark=true;
for(x=0;isdigit(ch);ch=getchar())x=x*10+ch-'0';
if(mark)x=-x;
}
struct Edge{
int from,to,res,w,Next;
Edge(int from,int to,int w,int res,int Next):from(from),to(to),w(w),res(res),Next(Next){}
};
vector<Edge> edge;
void Addedge(int from,int to,int w,int res){
edge.push_back(Edge(from,to,w,res,last[from]));
last[from]=edge.size()-1;
edge.push_back(Edge(to,from,-w,0,last[to]));
last[to]=edge.size()-1;
}
int path[maxn], dist[maxn];
bool vis[maxn];
struct SPFA{
int n;
void init(int n){
this->n =n;
memset(last,-1,sizeof(last));
}
bool find(int s,int t){
int i;
CLEAR(vis);
for(i=1;i<=n;i++) dist[i]=inf;
memset(path,-1,sizeof(path)) ;
dist[s]=0; path[s]=0 ;vis[s]=true;
queue <int> q; q.push(s);
while(!q.empty()){
int x=q.front();
q.pop();vis[x]=false;
for(i=last[x];i!=-1;i=edge[i].Next){
Edge& e=edge[i];
if(e.res>0&&dist[x]+e.w<dist[e.to]){
dist[e.to]=dist[x]+e.w;
path[e.to]=i;
if(!vis[e.to]){
q.push(e.to) ;
vis[e.to]=true;
}
}
}
}
return dist[t]<inf;
}
}spfa;
void Addflow(int s,int t){
int flow=inf,i;
for(i=t; i!=s&&edge[path[i]].from!=0;i=edge[path[i]].from)
flow=min(flow,edge[path[i]].res);
maxflow+=flow;
mincost+=dist[t];
for(i=t;i!=s;i=edge[path[i]].from){
int x=path[i];
edge[x].res-=flow;
edge[x^1].res+=flow;
}
}
int main(){
int i,j,k,x,y,z,cnt=0;
N=maxflow=mincost=0;
_read(n); _read(m);
spfa.init(N=n+2);
for(i=1;i<=m;i++){
_read(x); _read(y); _read(z);
Addedge(x,y,z,1);
Addedge(y,x,z,1);
}
Addedge(N-1,1,0,2);
Addedge(n,N,0,2);
while(spfa.find(N-1,N))Addflow(N-1,N);
cout<<mincost<<endl;
return 0;
}
最大流:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#define clear(xxx) memset(xxx,0,sizeof(xxx))
using namespace std;
const int inf=1e9;
int dis[4005],cnt[4005],n,x,y,z,m;
int N;
int tot_edge=0;
struct line{
int from,to,remain,acc;
int fan;
};
line edge[2000005];
int last[2005],_next[1000005];
void add_edge(int x,int y,int c,int accom){
tot_edge++;
edge[tot_edge].from=x;
edge[tot_edge].to=y;
edge[tot_edge].acc=accom;
edge[tot_edge].remain=c;
_next[tot_edge]=last[x];
last[x]=tot_edge;
tot_edge++;
edge[tot_edge].from=y;
edge[tot_edge].to=x;
edge[tot_edge].acc=0;
edge[tot_edge].remain=0;
_next[tot_edge]=last[y];
last[y]=tot_edge;
edge[tot_edge].fan=tot_edge-1;
edge[tot_edge-1].fan=tot_edge;
}
int sap(int u,int flow){
int v,temp,delta=0;
if(u==N+2)return flow;
for(int h=last[u];h;h=_next[h]){
v=edge[h].to;
if(edge[h].remain&&dis[u]==dis[v]+1){
temp=sap(v,min(flow-delta,edge[h].remain));
edge[h].remain-=temp;
edge[edge[h].fan].remain+=temp;
delta+=temp;
if(delta==flow||dis[N+1]>=N+2)return delta;
}
}
if(dis[N+1]>N+2)return delta;
cnt[dis[u]]--;
if(cnt[dis[u]]==0)dis[N+1]=N+2;
dis[u]++;
cnt[dis[u]]++;
return delta;
}
int main(){
int tot=0,i,j,k,t=0,t3,t4;
cin>>n>>m;
N=n+m;
for(i=1;i<=n;i++){
add_edge(i+m,N+2,1,1);
int x;
while(scanf("%d",&x)!=EOF&&x!=0){
add_edge(x,m+i,1,1);
}
}
for(i=1;i<=m;i++)add_edge(N+1,i,1,1);
while(dis[N+1]<N+2){
t+=sap(N+1,inf);
}
cout<<t;
}
dijkstra+heap:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
#define CLEAR(XXX) memset((XXX),0,sizeof(XXX))
using namespace std;
const int inf=1e9;
const int maxn=1005,maxm=1005;
int n,m;
inline void _read(int &x){
char ch=getchar(); bool mark=false;
for(;!isdigit(ch);ch=getchar())if(ch=='-')mark=true;
for(x=0;isdigit(ch);ch=getchar())x=x*10+ch-'0';
if(mark)x=-x;
}
struct Edge{
int from,to,w;
Edge(int from,int to,int w):from(from),to(to),w(w){}
};
struct node{ //建小根堆用
int d,u;
node (int d,int u):d(d),u(u){}
bool operator < (const node& a)const {
return d>a.d;
}
};
struct Dijstra{
int n,m;
vector<Edge> edge;
int last[maxm],Next[maxm],dist[maxn];
bool vis[maxn];
void init(int n){
this->n = n;
m=0;
CLEAR(last); CLEAR(Next);
edge.clear();
edge.push_back(Edge(0,0,0));
}
void add_edge(int from,int to,int dist){
edge.push_back(Edge(from,to,dist));
m=edge.size()-1;
Next[m]=last[from];
last[from]=m;
}
void solve(int s){
int i;
priority_queue <node> q;
CLEAR(vis);
for(i=1;i<=n;i++) dist[i]=inf;
dist[s]=0;
q.push(node(0,s));
while(!q.empty()){
int x=q.top().u;
q.pop();
for(i=last[x];i;i=Next[i]){
Edge& e=edge[i];
if(dist[e.from]+e.w<dist[e.to]){
dist[e.to]=dist[e.from]+e.w;
q.push(node(dist[e.to],e.to)) ;
}
}
}
}
int main(){
Dijstra solver;
int i,j,x,y,w;
_read(n);_read(m);
solver.init(n);
for(i=1;i<=m;i++){
_read(x);_read(y);_read(w);
solver.add_edge(x,y,w);
}
_read(x);_read(y);
solver.solve(x);
printf("%d",solver.dist[y]);
return 0;
}