zoukankan      html  css  js  c++  java
  • POJ 2195 Going Home【最小费用流 二分图最优匹配】

    题目大意:一个n*m的地图,上面有一些人man(m)和数量相等的house(H) 图上的距离为曼哈顿距离 问所有人住进一所房子(当然一个人住一间咯)距离之和最短是多少?

    思路:一个人一间房,明显是二分图的模型,边权为人和房子的曼哈顿距离,然后算一下最小距离即可 懒得学KM了 最小费用流的经典建图

    #include <stdio.h>

    #include <string.h>

    #include <algorithm>

    #include <queue>

    #include <iostream>

    #define maxn 40000

    #define inf 0x3f3f3f3f

    using namespace std;

    struct POINT

    {

        int x;

        int y;

    }a[maxn],b[maxn];

    int head[maxn],root[maxn],point[maxn],next[maxn];

    int flow[maxn],cost[maxn],pre[maxn],now=0,dist[maxn];

    int n,m,h,h2;

    char ch[maxn];

    int mabs(int x)

    {

        return x>0?x:-x;

    }

    int distanc(int i,int j)

    {

        return mabs(a[i].x-b[j].x)+mabs(a[i].y-b[j].y);

    }

    void add(int x,int y,int v,int c)

    {

        next[++now]=head[x];

        head[x]=now;

        point[now]=y;

        flow[now]=v;

        cost[now]=c;

        root[now]=x;

        next[++now]=head[y];

        head[y]=now;

        point[now]=x;

        flow[now]=0;

        cost[now]=-c;

        root[now]=y;

    }

    int spfa(int s,int t)

    {

        memset(pre,0,sizeof(pre));

        for(int i=0;i<=t;i++)dist[i]=inf;

        dist[s]=0;

        int visit[maxn]={0};

        visit[s]=1;

        queue<int>q;

        q.push(s);

        while(!q.empty())

        {

            int u=q.front();

            q.pop();

            visit[u]=0;

            for(int i=head[u];i;i=next[i])

            {

                int k=point[i];

                if(dist[u]+cost[i]<dist[k] && flow[i]!=0)

                {

                    pre[k]=i;

                    dist[k]=dist[u]+cost[i];

                    if(!visit[k])

                    {

                        visit[k]=1;

                        q.push(k);

                    }

                }

            }

        }

        return dist[t]!=inf;

    }

    int main()

    {

        while(1)

        {

            scanf("%d%d",&n,&m);

            if(n==0&&m==0)break;

            now=0;

            memset(head,0,sizeof(head));

            int ans=0;

            h=h2=0;

            for(int i=1;i<=n;i++)

            {

                scanf("%s",ch+1);

                for(int j=1;j<=m;j++)

                {

                    if(ch[j]=='H')a[++h].x=i,a[h].y=j;

                    else if(ch[j]=='m')b[++h2].x=i,b[h2].y=j;

                }

            }

            for(int i=1;i<=h;i++)

            {

                for(int j=1;j<=h;j++)

                {

                    int u=distanc(i,j);

                    add(j,i+h+1,1,u);

                }

            }

            int s=h*2+10,t=h*2+11;

            for(int i=1;i<=h;i++)add(s,i,1,0);

            for(int i=1;i<=h;i++)add(i+h+1,t,1,0);

            while(spfa(s,t))

            {

                int e=pre[t],minx=flow[e];

                while(e)

                {

                    if(flow[e]<minx)minx=flow[e];

                    e=pre[root[e]];

                }

                e=pre[t];

                while(e)

                {

                    flow[e]-=minx;

                    flow[((e-1)^1)+1]+=minx;

                    e=[root[e]];

                }

                ans+=dist[t]*minx;

            }

            printf("%d ",ans);

        }

        return 0;

    }

  • 相关阅读:
    Why Visual Studio Team System Isn't A LoadRunner Killer[转载]
    从键盘判断电脑主人
    LoadRunner中添加weblogic监视器(JMX)
    winrunner事务概念的代码应用(毫秒级)
    Delphi中的线程类
    换工作时如何提高自身的待遇(转贴)
    牛人是怎样用函数实现本地化测试的
    肯德基的见闻
    由 12306.cn 谈谈网站性能技术
    20个优秀的 CSS 网格系统(CSS Grid Systems)推荐
  • 原文地址:https://www.cnblogs.com/philippica/p/4104461.html
Copyright © 2011-2022 走看看