hdu 1533 && pku 2195 最小费用最大流

来源:互联网 发布:淘宝试衣镜 编辑:程序博客网 时间:2024/05/01 00:17

#include<iostream>
#include<cstdio>
#include<queue>
#include<string>
#define INF 0x3f3f3f3f
using namespace std;
const int V = 205;
const int E = 25000;
struct node{
 int x,y;
}man[V],home[V];
struct Edge{
 int u,v,c,flow;
 int next;
}edg[E];
int head[V],dis[V],prev[V],pree[V];
bool hash[V];
int n,m,e,src,End,mcnt,hcnt;
char map[105][105];
inline void addedge(int u,int v,int c,int flow)
{
 edg[e].u = u; edg[e].c = c; edg[e].v = v;
 edg[e].flow = flow; edg[e].next = head[u];
 head[u] = e++;
}
inline void Insert(int u,int v,int c,int flow)
{
 addedge(u,v,c,flow);
 addedge(v,u,-c,0); //反向边 费用为-c 容量为0
}
int spfa()
{
 queue<int>q;
 int now,i,v;
 memset(hash,false,sizeof(hash));
 memset(prev,-1,sizeof(prev));
 memset(dis,0x3f,sizeof(dis));
 dis[src] = 0;
 hash[src] = true;
 q.push(src);
 while(!q.empty())
 {
  now = q.front();
  q.pop();
  hash[now] = false;
  for(i = head[now]; i != -1; i = edg[i].next)
  {
   v = edg[i].v;
   if(edg[i].flow && dis[now] + edg[i].c < dis[v])
   {
    dis[v] = dis[now] + edg[i].c;
    prev[v] = now; pree[v] = i;
    if(!hash[v])
    {
     hash[v] = true;
     q.push(v);
    }
   }
  }
 }
 return (prev[End] != -1);
}
int mincost_maxflow()
{
 int flow = 0,cost = 0;
 int i,t,te;
 while(spfa())
 {
  i = End;t = INF;
  while(i != src){
   te = pree[i];i = prev[i];
   if(edg[te].flow < t)
   {
    t = edg[te].flow;
   } 
  }
  i = End;
  while(i != src){
   te = pree[i];i = prev[i];
   edg[te].flow -= t;
   edg[te^1].flow += t;
  }
  flow += t; cost += dis[End];
 }
 return cost;
}
void solve()
{
 char c;
 int i,j,tc;
 while(scanf("%d %d",&n,&m) != EOF && (n + m))
 {
  memset(head,-1,sizeof(head));
  e = src = mcnt = hcnt = 0;
  for(i = 0; i < n; i++){
   scanf("%s",&map[i]);
   for(j = 0; j < m; j++){
    if(map[i][j] == 'H'){
     home[hcnt].x = i;home[hcnt++].y = j;
    }
    else if(map[i][j] == 'm'){
     man[mcnt].x = i;man[mcnt++].y = j;
    }
   }
  }
  End = mcnt + hcnt + 1;
  for(i = 0; i < mcnt; i++)
  {
   Insert(src,i + 1,0,1);  //源点到小孩
   Insert(i + mcnt + 1,End,0,1);//家到汇点
   for(j = 0; j < hcnt; j++)
   {
    tc = abs(man[i].x - home[j].x) + abs(man[i].y - home[j].y);
    Insert(i + 1,j + mcnt + 1,tc,1);    
   }
   
  }
  printf("%d/n",mincost_maxflow());
 }
}
int main()
{
 solve();
 return 0;
}

原创粉丝点击