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 }

 

你可能感兴趣的:(home)