zoukankan      html  css  js  c++  java
  • HDU1533 Going Home(最小费用最大流 spfa模版)

    题意:

    给你一个N行M列的矩阵,其中“.”代表空地,“H”代表房子,“m”代表人,其中有n个房子和n个人。现在要求每个人进入一间房子,且人走一步需要支付1美元。

    求最小需要花费多少美元才能让所有人都进入到房子中(每个人只能进入一间房子,每个房子只能容纳一个人)。

    建图思路与安排工作那道题一样,设置一个超级源点(我习惯设置为0)和一个超级汇点,然后超级源点连接每个人(流量为1费用为0),

    每个人连接每个房子(流量为1费用为人与房子的距离),然后每个房子连接超级汇点(流量为1费用为0)。

    跑一遍spfa模版就出来了。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <cmath>
    #include <vector>
    #include <algorithm>
    #include <limits.h>
    using namespace std;
    #define inf 1e8
    #define maxn 205
    #define maxm 100000
    int head[maxn],eid;
    int dis[maxn];
    bool vis[maxn];
    int a[maxn];
    int pre[maxn];
    int cnt1,cnt2,cnt,result;
    int hx[maxn],hy[maxn],mx[maxn],my[maxn],cap[maxn][maxn];
    struct node
    {
        int u,v,cap,next,cost;
    }eg[maxm];
    int fun(int x,int y)
    {
        return fabs(mx[x]-hx[y])+fabs(my[x]-hy[y]);
    }
    void add(int u,int v,int cap,int cost)
    {
        eg[eid].u=u;
        eg[eid].v=v;
        eg[eid].cap=cap;
        eg[eid].next=head[u];
        eg[eid].cost=cost;
        head[u]=eid++;
        eg[eid].u=v;
        eg[eid].v=u;
        eg[eid].cap=0;
        eg[eid].next=head[v];
        eg[eid].cost=-cost;
        head[v]=eid++;
    }
    void makemap()
    {
        for(int i=1;i<=cnt2;i++)
        {
            add(0,i,1,0);
            for(int j=1;j<=cnt1;j++)
            {
                add(i,cnt2+j,1,fun(i,j));
            }
        }
        for(int j=1;j<=cnt1;j++)
            add(cnt2+j,cnt,1,0);
    }
    bool spfa(int s,int t,int &flow,int &cost)
    {
        memset(vis,false,sizeof(vis));
        for(int i=0;i<maxn;i++)
            dis[i]=inf;
        dis[s]=0;
        vis[s]=true;
        pre[s]=0;
        a[s]=inf;
        queue<int>q;
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            vis[u]=false;
            for(int i=head[u];i!=-1;i=eg[i].next)
            {
                if(eg[i].cap&&dis[eg[i].v]>dis[u]+eg[i].cost)
                {
                    dis[eg[i].v]=dis[u]+eg[i].cost;
                    pre[eg[i].v]=i;
                    a[eg[i].v]=min(a[u],eg[i].cap);
                    if(!vis[eg[i].v])
                    {
                        q.push(eg[i].v);
                        vis[eg[i].v]=true;
                    }
                }
            }
        }
        if(dis[t]==inf) return false;
        flow+=a[t];
        cost+=dis[t]*a[t];
        int u=t;
        while(u!=s)
        {
            eg[pre[u]].cap-=a[t];
            eg[pre[u]^1].cap+=a[t];
            u=eg[pre[u]].u;
        }
        return true;
    }
    int mincost(int s,int t)
    {
        int flow=0,cost=0;
        while(spfa(s,t,flow,cost));
        return cost;
    }
    void init()
    {
        memset(head,-1,sizeof(head));
        eid=0;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int n,m;
        char s[maxn];
        while(~scanf("%d%d",&n,&m)&&n)
        {
            init();
            cnt1=cnt2=0;
            for(int i=0;i<n;i++)
            {
                scanf("%s",s);
                for(int j=0;s[j]!='';j++)
                {
                    if(s[j]=='H')
                    {
                        cnt1++;
                        hx[cnt1]=i;
                        hy[cnt1]=j;
                    }
                    else if(s[j]=='m')
                    {
                        cnt2++;
                        mx[cnt2]=i;
                        my[cnt2]=j;
                    }
                }
            }
            cnt=cnt1+cnt2+1;
            makemap();
            printf("%d
    ",mincost(0,cnt));
        }
        return 0;
    }
  • 相关阅读:
    spring @component的作用
    Spring 开启Annotation <context:annotation-config> 和 <context:component-scan>诠释及区别
    servlet中实现页面跳转return “r:”和return “f:
    MyEclipse中SVN的使用方法 此博文包含图片 (2012-04-19 12:18:35)
    MyEclipse使用总结——MyEclipse10安装SVN插件
    javaweb学习总结(九)—— 通过Servlet生成验证码图片
    Spring-springmvc-mybatis整合
    MyBatis连接SQLServer数据库
    mybatis入门基础(二)----原始dao的开发和mapper代理开发
    MyBatis入门基础(一)
  • 原文地址:https://www.cnblogs.com/d-e-v-i-l/p/4769223.html
Copyright © 2011-2022 走看看