POJ 2195 Going Home(最小费用最大流)

题目链接

最小费用最大流算法 就好像是EK的变形。bfs的时候类似spfa找最短路,更新cost。

因为我是从 EK 的代码基础上改的,然后没发现if(u == end) break;和这个不一样。。。一直WA,注意数组开大一点。

先搜到的不一定是最优结果啊!!!

最小费用 最大流 邻接表模版。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cmath>
  4 #include <queue>
  5 using namespace std;
  6 #define INF 0x7fffffff
  7 int low[1001],path[1001];
  8 struct node
  9 {
 10     int u,v,w,next,re,cost;
 11 }edge[501*201];
 12 int first[1001],dis[1001],in[1001];
 13 int str,end,n,m,t;
 14 char ch[501][501];
 15 struct point
 16 {
 17     int x,y;
 18 }queh[1001],quem[1001];
 19 int Abs(int a)
 20 {
 21     return a >= 0?a:-a;
 22 }
 23 void CL()
 24 {
 25     t = 1;
 26     memset(first,-1,sizeof(first));
 27 }
 28 void add(int u,int v,int w,int cost)
 29 {
 30     edge[t].u = u;
 31     edge[t].v = v;
 32     edge[t].w = w;
 33     edge[t].re = t+1;
 34     edge[t].cost = cost;
 35     edge[t].next = first[u];
 36     first[u] = t ++;
 37 
 38     edge[t].u = v;
 39     edge[t].v = u;
 40     edge[t].w = 0;
 41     edge[t].re = t-1;
 42     edge[t].cost = -cost;
 43     edge[t].next = first[v];
 44     first[v] = t ++;
 45 }
 46 int bfs()
 47 {
 48     int u,v,i;
 49     memset(path,-1,sizeof(path));
 50     for(i = 0;i <= end;i ++)
 51     {
 52         dis[i] = INF;
 53         in[i] = 0;
 54     }
 55     queue<int> que;
 56     que.push(str);
 57     in[str] = 1;
 58     dis[str] = 0;
 59     low[str] = INF;
 60     while(!que.empty())
 61     {
 62         u = que.front();
 63         in[u] = 0;
 64         que.pop();
 65         for(i = first[u]; i != -1; i = edge[i].next)
 66         {
 67             v = edge[i].v;
 68             if(edge[i].w&&dis[v] > dis[u] + edge[i].cost)
 69             {
 70                 low[v] = low[u] < edge[i].w ? low[u]:edge[i].w;
 71                 path[v] = i;
 72                 dis[v] = dis[u] + edge[i].cost;
 73                 if(!in[v])
 74                 {
 75                     que.push(v);
 76                     in[v] = 1;
 77                 }
 78             }
 79         }
 80     }
 81     if(path[end] == -1)
 82         return -1;
 83     else
 84         return low[end];
 85 }
 86 int mcmf()
 87 {
 88     int ans = 0,res,now,temp;
 89     while((res = bfs()) != -1)
 90     {
 91         now = end;
 92         while(now != str)
 93         {
 94             temp = path[now];
 95             edge[edge[temp].re].w += res;
 96             edge[temp].w -= res;
 97             ans += res*edge[temp].cost;
 98             now = edge[temp].u;
 99         }
100     }
101     return ans;
102 }
103 int build()
104 {
105     int i,j,numh = 1,numm = 1;
106     for(i = 0;i < n;i ++)
107     {
108         for(j = 0;j < m;j ++)
109         {
110             if(ch[i][j] == 'm')
111             {
112                 quem[numm].x = i;
113                 quem[numm].y = j;
114                 numm ++;
115             }
116             else if(ch[i][j] == 'H')
117             {
118                 queh[numh].x = i;
119                 queh[numh].y = j;
120                 numh ++;
121             }
122         }
123     }
124     numm --;
125     numh --;
126     for(i = 1;i <= numm;i ++)
127     {
128         for(j = 1;j <= numh;j ++)
129         {
130             int d;
131             d = Abs(quem[i].x-queh[j].x)+Abs(quem[i].y-queh[j].y);
132             add(i,numm+j,1,d);
133         }
134     }
135     for(i = 1;i <= numm;i ++)
136     {
137         add(0,i,1,0);
138     }
139     for(i = 1;i <= numm;i ++)
140     {
141         add(numm+i,2*numm+1,1,0);
142     }
143     return 2*numm;
144 }
145 int main()
146 {
147     int i;
148     while(scanf("%d%d",&n,&m)!=EOF)
149     {
150         if(n == 0&&m == 0) break;
151         CL();
152         for(i = 0;i < n;i ++)
153         scanf("%s",ch[i]);
154 
155         str = 0;end = build()+1;
156         printf("%d\n",mcmf());
157     }
158     return 0;
159 }

 

posted @ 2013-02-25 17:11  Naix_x  阅读(213)  评论(0编辑  收藏  举报