最小费用最大流模板(存边)
来源:互联网 发布:信用证是什么意思知乎 编辑:程序博客网 时间:2024/06/06 21:40
函数功能介绍:
Addedge(from,to,w,res) 添加一条 x->y,费用为w,残量为res的边,并一起添加其反向边,由于从0号开始,相邻两个数代表的边互为反向边(即i号边的反向边是 i^1)。
spfa.init(N)初始化点数N
spfa.find(S,T) 在 源点为S,汇点为T的图中寻找最小费用增广路,i号点的前驱边编号存在Path[i]中
代码如下(以nkoj 1589为例):
#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>#include<queue>using namespace std;const long long inf=1000000000;long long n,p,tk,tm,wk,wm;long long N;long long maxflow;long long mincost;long long tot_edge=0;long long flow,cost;long long dis[10005],path[10005];long long a[10005];bool flag[10005];struct line{long long from,to,len,remain,fan;};line edge[5000005];long long last[10005],_next[5000005];void add_edge(long long x,long long y,long long l,long long acc){tot_edge++;edge[tot_edge].from=x;edge[tot_edge].to=y;edge[tot_edge].len=l;edge[tot_edge].remain=acc;edge[tot_edge].fan=tot_edge+1;_next[tot_edge]=last[x];last[x]=tot_edge;tot_edge++;edge[tot_edge].from=y;edge[tot_edge].to=x;edge[tot_edge].len=-l;edge[tot_edge].remain=0;edge[tot_edge].fan=tot_edge-1;_next[tot_edge]=last[y];last[y]=tot_edge;}bool findpath(){queue<long long> q; long long i,j,now; for(i=1;i<=N+2;i++){ dis[i]=inf; path[i]=-1;flag[i]=false;} dis[N+1]=path[N+1]=0;flag[N+1]=true; q.push(N+1); while(q.size()){ j=q.front(); q.pop();flag[j]=false; for(long long h=last[j];h;h=_next[h]){ int v=edge[h].to; if(edge[h].remain&&(dis[v]>dis[j]+edge[h].len)){ dis[v]=dis[j]+edge[h].len; path[v]=h; if(flag[v]==false){ flag[v]=true; q.push(v);}}} } if(dis[N+2]<inf)return true; else return false; }void addflow(){long long flow,cost,i;flow=inf;cost=0;i=N+2;while((i!=N+1)&&(path[i]!=0)){flow=min(flow,edge[path[i]].remain);cost+=edge[path[i]].len; //edge[edge[path[i]].fan].len=-edge[edge[path[i]].fan].len;i=edge[path[i]].from;} maxflow+=flow; mincost+=flow*cost;i=N+2;while(i!=N+1){edge[path[i]].remain-=flow;edge[edge[path[i]].fan].remain+=flow;i=edge[path[i]].from;}}int main(){long long i,j,sum=0;cin>>n>>p>>tk>>wk>>tm>>wm;N=2*n;for(i=1;i<=n;i++)scanf("%I64d",&a[i]);for(i=1;i<=n;i++){add_edge(N+1,i,0,a[i]);add_edge(N+1,i+n,p,inf);if(i!=n)add_edge(i,i+1,0,inf);}for(i=1;i<=n;i++){if(i+tk<=n)add_edge(i,i+n+tk,wk,inf);if(i+tm<=n)add_edge(i,i+n+tm,wm,inf);add_edge(i+n,N+2,0,a[i]);}maxflow=0; mincost=0;while(findpath())addflow(); printf("%I64d\n",mincost);}
0 0
- 最小费用最大流模板(存边)
- [存模板]最小费用最大流 MCMF
- 最小费用最大流(讲解+模板)
- 最大流最小费用(模板)
- 最小费用最大流(模板)
- 最小费用最大流(模板)
- (洛谷 最小费用最大流 模板)
- 模板[最小费用最大流]
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流,模板
- 最小费用最大流模板
- 最小费用最大流 模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 如何学好游戏3D引擎编程
- hdu1532 当前弧优化的dinic算法实现
- 利用MySQL排序将树结构表数据封装成树结构对象(三)
- sybase中插入多条数据
- IO中同步、异步与阻塞、非阻塞的区别
- 最小费用最大流模板(存边)
- 多校联合训练4&&HDU 5763
- hdu 2041 超级楼梯
- POJ 2531 Network Saboteur
- 2016多校联合训练赛 第四场1012 Bubble Sort hdu 5775
- sphinx与中文分词coreseek(window)
- bootstrap, boosting, bagging 几种方法的区别与联系
- [正则表达式]-基础语法一 元字符之定位符
- 服务的启动方式