網路流相關演算法模板
阿新 • • 發佈:2019-01-29
#define INF 0x7fffffff //最小費用流模板 #define MAX_V 1005 typedef pair<int,int> P;//first儲存最短距離,second儲存頂點編號 //用於表示邊的結構體(終點,容量,費用反向邊) struct edge { int to,cap,cost,rev; }; int V;//頂點數 vector<edge> G[MAX_V];//圖的鄰接表表示 int h[MAX_V];//頂點的勢 int dist[MAX_V];//最短距離 int prevv[MAX_V],preve[MAX_V];//最短路中的前驅結點和對應的邊 //向圖中增加一條從from到to容量為cap費用為cost的邊 void add_edge(int from,int to,int cap,int cost) { G[from].push_back((edge){to,cap,cost,G[to].size()}); G[to].push_back((edge){from,0,-cost,G[from].size()-1}); } //求解從s到t流量為f的最小費用流 //如果不能再增廣則返回-1 int min_cost_flow(int s,int t,int f) { int res=0; fill(h,h+V,0);//初始化h while(f>0){ //使用Dijkstra演算法更新h priority_queue<P,vector<P>,greater<P> > que; fill(dist,dist+V,INF); dist[s]=0; que.push(P(0,s)); while(!que.empty()){ P p=que.top(); que.pop(); int v=p.second; if(dist[v]<p.first) continue; for(int i=0;i<G[v].size();i++){ edge &e=G[v][i]; if(e.cap>0&&dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){ dist[e.to]=dist[v]+e.cost+h[v]-h[e.to]; prevv[e.to]=v; preve[e.to]=i; que.push(P(dist[e.to],e.to)); } } } if(dist[t]==INF){ //不能再增廣 return -1; } for(int v=0;v<V;v++){ h[v]+=dist[v]; } //沿s到t的最短路儘量增廣 int d=f; for(int v=t;v!=s;v=prevv[v]){ d=min(d,G[prevv[v]][preve[v]].cap); } f-=d; res+=d*h[t]; for(int v=t;v!=s;v=prevv[v]){ edge &e=G[prevv[v]][preve[v]]; e.cap-=d; G[v][e.rev].cap+=d; } } return res; } //模板