最小费用最大流

来源:互联网 发布:sql语句修改字段属性 编辑:程序博客网 时间:2024/04/29 14:14

hdu1533Going Home http://acm.hdu.edu.cn/showproblem.php?pid=1533

题意:给出NxM的地图,'.'表示可以走的,'H'表示家,'m'表示人,H和m的数目相同,求把所有人移动到H的最小步数(一个H只能放一个m)

另外一个也是很赞:http://blog.csdn.net/hnust_xiehonghao/article/details/10298937

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>#include <string>#include <vector>#include <set>#include <queue>#include <stack>#define PI 3.1415926using namespace std;typedef long long LL;#define MAX 206#define INF 0x3f3f3f3fchar ch[MAX][MAX];int S ,E,Index;int Value[MAX][MAX],Map[MAX][MAX],pre[MAX];int path[MAX],dis[MAX],vis[MAX],listb[1000000];struct nnode{    int c,w,to,next;} Edge[200 * 200 * 2];struct NM{    int x,y;} nman[MAX * MAX];struct NH{    int x,y;} nhouse[MAX * MAX];void Add_edge(int a,int b,int c,int w){    Value[a][b] = w;    if(c >= 0)Map[a][b] = c;    Edge[Index].c = c;    Edge[Index].to = b;    Edge[Index].w = w;    Edge[Index].next = pre[a];    pre[a] = Index ++;}bool BFS(){    int s = 0,e = 0;    memset(path,-1,sizeof(path));    memset(dis,INF,sizeof(dis));    memset(vis,0,sizeof(vis));    listb[s++] = S;    vis[S] = 1;    dis[S] = 0;    while(s != e)    {        int v = listb[e ++];        vis[v] = 0;        for(int i = pre[v]; i != -1; i = Edge[i].next)        {            int vv = Edge[i].to;            if(Map[v][vv] > 0 && (dis[vv] == INF || dis[vv] > dis[v] + Edge[i].w))            {                path[vv] = v;                dis[vv] = dis[v] + Edge[i].w;                if(!vis[vv])                {                    vis[vv] = 1;                    listb[s++] = vv;                }            }        }    }    if(dis[E] == INF)return false;    return true;}int Find(){    int sum = 0,MIN = INF;    for(int i = E; i != -1; i = path[i])    {        if(path[i] != -1)        {            MIN = min(MIN,Map[path[i]][i]);        }    }    for(int i = E; i != -1; i = path[i])    {        if(path[i] != -1)        {            Map[path[i]][i] -= MIN;            Map[i][path[i]] += MIN;            sum += Value[path[i]][i];        }    }    return sum ;}int main(){//    freopen("in.txt","r",stdin);    int n,m;    while(~scanf("%d%d",&n,&m) && n && m)    {        memset(pre,-1,sizeof(pre));        memset(Map,0,sizeof(Map));        memset(Value,0,sizeof(Value));        int M = 0;        int H = 0;        for(int i = 1; i <= n; i++)        {            getchar();            for(int j = 1; j <= m; j++)            {                scanf("%c",&ch[i][j]);                if(ch[i][j] == 'm')                {                    M ++;                    nman[M].x = i;                    nman[M].y = j;                }                else if(ch[i][j] == 'H')                {                    H ++;                    nhouse[H].x = i;                    nhouse[H].y = j;                }            }        }        S = 0;        Index = 0;        E = M + H + 1;        for(int i = 1; i <= M; i++)        {            Add_edge(S,i,1,0);            Add_edge(i,S,-1,0);        }        for(int i = M + 1; i <= M + H; i++)        {            Add_edge(i,E,1,0);            Add_edge(E,i,-1,0);        }        for(int i = 1; i <= M; i++)        {            for(int j = 1 ; j <= H; j++)            {                int d = abs(nman[i].x - nhouse[j].x) + abs(nman[i].y - nhouse[j].y);                Add_edge(i,j + M,1,d);                Add_edge(j + M,i,-1,-d);            }        }        int sum = 0;        while(BFS())        {            sum += Find();        }        printf("%d\n",sum);    }    return 0;}

转载自:http://www.geekcome.com/content-10-3043-1.html

0 0
原创粉丝点击