POJ 2195 Going Home 最小费用最大流
生活随笔
收集整理的這篇文章主要介紹了
POJ 2195 Going Home 最小费用最大流
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這題目同時也可以用KM()算法做,最求小權值匹配而已,權值設置為負數就行,具體KM算法參照:http://blog.csdn.net/cnh294141800/article/details/18952979
最小費用最大流:
還是主要尋找個增廣路,用spfa尋找增廣路。
鄰接表存。
這是個模板題:
構圖的話,設置一個超級源點,超級匯點,再人一個集合,房子一個集合,人在任何每個房子間連一條流量為1,費用為距離的邊,超級源點和人連 流量為1,費用為0,,房子和超級匯點間也同樣連邊。
#include<cstdio> #include<queue> #include<cstring> #include<algorithm> #include<iostream> using namespace std;const int maxn=1000,maxm=100000,inf=1<<26;struct Edge {Edge(){};Edge(int a,int b,int c,int d) {v=a; f=b; w=c; nxt=d;}int v,f,w,nxt; };struct point {int x,y; } hh[300],mm[300];int g[maxn+10]; struct Edge e[maxm+10]; int nume; int src,sink; char Map[300][300];queue<int>que; bool inQue[maxn+10]; int dist[maxn+10]; int pree[maxn+10],prev[maxn+10];void add(int u,int v,int f,int w) {e[++nume] = Edge(v,f,w,g[u]);g[u]=nume;e[++nume] = Edge(u,0,-w,g[v]);g[v]=nume; }bool findPath() {while(!que.empty()) que.pop();que.push(src);int i;//memeset(dist,63,sizeof(dist));for(i=0;i<=sink+10;i++) dist[i]=inf;dist[src]=0;inQue[src]=true;while(!que.empty()){int u=que.front();que.pop();for(i = g[u]; i ; i=e[i].nxt){if(e[i].f>0&&dist[u]+e[i].w<dist[e[i].v]){dist[e[i].v]=dist[u]+e[i].w;prev[e[i].v]=u;pree[e[i].v]=i;if(!inQue[e[i].v]){inQue[e[i].v]=true;que.push(e[i].v);}}}inQue[u]=false;}if(dist[sink] < inf ) return true;return false; }int augment() {int u=sink;int delta=inf;while(u!=src){if(e[pree[u]].f<delta) delta=e[pree[u]].f;u=prev[u];}u=sink;while(u!=src){e[pree[u]].f-=delta;e[pree[u]^1].f+=delta;u=prev[u];}return dist[sink]*delta; } int mincostflow() {int cur=0;while(findPath()){cur+=augment();}return cur; } int main() {int n,m,i,j;while(scanf("%d%d",&n,&m),m||n){getchar();memset(g,0,sizeof(g));nume=1;int mh1=0,mh2=0;for(i=0;i<n;i++){for(j=0;j<m;j++){scanf("%c",&Map[i][j]);if(Map[i][j]=='H') {hh[mh1].x=i;hh[mh1++].y=j;}if(Map[i][j]=='m'){mm[mh2].x=i;mm[mh2++].y=j;}}getchar();}int mh=mh1;src=0;sink=2*mh+1;for(i=1;i<=mh;i++) add(0,i,1,0);for(i=mh+1;i<=2*mh;i++) add(i,2*mh+1,1,0);for(i=0;i<mh;i++)for(j=0;j<mh;j++){int tempx=hh[i].x-mm[j].x;int tempy=hh[i].y-mm[j].y;add(i+1,mh+j+1,1,abs(tempx)+abs(tempy));}printf("%d\n",mincostflow());} }總結
以上是生活随笔為你收集整理的POJ 2195 Going Home 最小费用最大流的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络流EK算法
- 下一篇: hdu 1565 方格取数(1)