hdu 1533 going home (最小费用最大流)

来源:互联网 发布:网站结构图制作软件 编辑:程序博客网 时间:2024/04/28 02:22

hdu 1533 going home (最小费用最大流)

思路: 在一个n*m的矩形区域,有多个房子和多个人,问一个人选一个房子,一个人走到房子的花费为人和房子之间的曼哈顿距离,问所有人都走到房子里,总花费最小是多少?

题解:经典的MCMF,建图:虚拟一个源点source,和一个汇点sink,source指向所有人,每条边的权值为1,

每个房子都指向汇点,权值为1,对于一个人,和每个房子都有一条边,权值为1。

注意:还有一个花费数组,cost[][],记录人和房子间的距离,注意要和流量图一样建立反向边!原因如下图:


#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <stack>#include <cmath>#include <vector>#include <queue>#include <map>#include <set>using namespace std;#define LL long long#define M 205#define N 102#define DEBUG puts("It's here!")#define INF 1<<29#define CLS(x,v) memset(x,v,sizeof(x))#define FOR(i,a,n)  for(int i=(a);i<=(n);++i)int cap[M][M],cost[M][M];int father[M],d[M];bool vis[M];int sourse,sink;void spfa(){    queue<int> Q;    CLS(vis,0);    CLS(father,-1);    for(int i=sourse;i<=sink;i++)d[i]=INF;    d[sourse]=0;    Q.push(sourse);    int pre;    while(!Q.empty())    {        pre=Q.front();        Q.pop();        vis[pre]=0;        for(int i=sourse;i<=sink;i++)        if(cap[pre][i]&&d[i]>d[pre]+cost[pre][i])        {            d[i]=d[pre]+cost[pre][i];            father[i]=pre;            if(!vis[i])            {                vis[i]=1;                Q.push(i);            }        }    }}void MCMF(){    int mincost=0;    while(1)    {        spfa();        if(father[sink]==-1)break;//汇点不可达        for(int i=sink;i!=sourse;i=father[i])        {            cap[father[i]][i]-=1;            cap[i][father[i]]+=1;        }        mincost+=d[sink];    }    printf("%d\n",mincost);}struct position{    int x,y;} man[N],house[N];int main(){    char s[N];    int n,m;    int a,b;    while(~scanf("%d%d",&n,&m)&&(n||m))    {        a=b=0;        CLS(cap,0);        CLS(cost,0);        for(int i=0; i<n; i++)        {            scanf("%s",s);            for(int j=0; j<m; j++)            {                if(s[j]=='m')                    man[++a].x=i,man[a].y=j;                if(s[j]=='H')                    house[++b].x=i,house[b].y=j;            }        }        //构图        sourse=0;sink=a+b+1;        for(int i=1; i<=a; i++)        {            cap[0][i]=1;            for(int j=1; j<=b; j++)            {                cap[i][a+j]=1;                cost[i][a+j]=abs(man[i].x-house[j].x)+abs(man[i].y-house[j].y);                cost[a+j][i]=-cost[i][a+j];            }        }        for(int i=a+1; i<sink; i++)            cap[i][sink]=1;        MCMF();    }    return 0;}







0 0
原创粉丝点击