POJ 2195 Going Home(最小费用最大流)
2013-02-25 17:11
369 查看
题目链接
最小费用最大流算法 就好像是EK的变形。bfs的时候类似spfa找最短路,更新cost。
因为我是从 EK 的代码基础上改的,然后没发现if(u == end) break;和这个不一样。。。一直WA,注意数组开大一点。
先搜到的不一定是最优结果啊!!!
最小费用 最大流 邻接表模版。
最小费用最大流算法 就好像是EK的变形。bfs的时候类似spfa找最短路,更新cost。
因为我是从 EK 的代码基础上改的,然后没发现if(u == end) break;和这个不一样。。。一直WA,注意数组开大一点。
先搜到的不一定是最优结果啊!!!
最小费用 最大流 邻接表模版。
#include <cstdio> #include <cstring> #include <cmath> #include <queue> using namespace std; #define INF 0x7fffffff int low[1001],path[1001]; struct node { int u,v,w,next,re,cost; }edge[501*201]; int first[1001],dis[1001],in[1001]; int str,end,n,m,t; char ch[501][501]; struct point { int x,y; }queh[1001],quem[1001]; int Abs(int a) { return a >= 0?a:-a; } void CL() { t = 1; memset(first,-1,sizeof(first)); } void add(int u,int v,int w,int cost) { edge[t].u = u; edge[t].v = v; edge[t].w = w; edge[t].re = t+1; edge[t].cost = cost; edge[t].next = first[u]; first[u] = t ++; edge[t].u = v; edge[t].v = u; edge[t].w = 0; edge[t].re = t-1; edge[t].cost = -cost; edge[t].next = first[v]; first[v] = t ++; } int bfs() { int u,v,i; memset(path,-1,sizeof(path)); for(i = 0;i <= end;i ++) { dis[i] = INF; in[i] = 0; } queue<int> que; que.push(str); in[str] = 1; dis[str] = 0; low[str] = INF; while(!que.empty()) { u = que.front(); in[u] = 0; que.pop(); for(i = first[u]; i != -1; i = edge[i].next) { v = edge[i].v; if(edge[i].w&&dis[v] > dis[u] + edge[i].cost) { low[v] = low[u] < edge[i].w ? low[u]:edge[i].w; path[v] = i; dis[v] = dis[u] + edge[i].cost; if(!in[v]) { que.push(v); in[v] = 1; } } } } if(path[end] == -1) return -1; else return low[end]; } int mcmf() { int ans = 0,res,now,temp; while((res = bfs()) != -1) { now = end; while(now != str) { temp = path[now]; edge[edge[temp].re].w += res; edge[temp].w -= res; ans += res*edge[temp].cost; now = edge[temp].u; } } return ans; } int build() { int i,j,numh = 1,numm = 1; for(i = 0;i < n;i ++) { for(j = 0;j < m;j ++) { if(ch[i][j] == 'm') { quem[numm].x = i; quem[numm].y = j; numm ++; } else if(ch[i][j] == 'H') { queh[numh].x = i; queh[numh].y = j; numh ++; } } } numm --; numh --; for(i = 1;i <= numm;i ++) { for(j = 1;j <= numh;j ++) { int d; d = Abs(quem[i].x-queh[j].x)+Abs(quem[i].y-queh[j].y); add(i,numm+j,1,d); } } for(i = 1;i <= numm;i ++) { add(0,i,1,0); } for(i = 1;i <= numm;i ++) { add(numm+i,2*numm+1,1,0); } return 2*numm; } int main() { int i; while(scanf("%d%d",&n,&m)!=EOF) { if(n == 0&&m == 0) break; CL(); for(i = 0;i < n;i ++) scanf("%s",ch[i]); str = 0;end = build()+1; printf("%d\n",mcmf()); } return 0; }
相关文章推荐
- POJ 2195 Going Home【最小费用最大流】
- 最小费用最大流-POJ-2195-Going Home
- poj 2195 Going Home(最小费用最大流)
- poj2195 Going Home 最小费用最大流
- POJ 2195 Going Home (最小费用最大流)
- POJ 2195 Going Home (最小费用最大流)
- POJ 2195 Going Home 最小费用最大流
- POJ 2195 Going Home(最小费用最大流)
- POJ 2195 Going Home 最小费用最大流 尼玛,心累
- poj-2195-Going Home最小费用最大流
- POJ - 2195 Going Home(最小费用最大流)
- POJ-2195 Going Home (最小费用最大流初学 && 最大权二分匹配—KM算法)
- POJ 2195 Going Home (最小费用最大流)
- poj 2195 Going Home【最小费用最大流】
- POJ_2195_Going Home_最小费用最大流
- hdu 1533 || poj 2195 Going Home (最小费用最大流)
- poj 2195 Going Home--最小费用最大流--spfa--动态数组--或者用 最小权匹配
- poj 2195 Going Home(最小费用最大流)
- poj 2195 Going Home(最小费用最大流)
- POJ 2195 Going Home 最小费用最大流