Going Home (hdu 1533 最小费用流)

集训的图论都快结束了,我才看懂了最小费用流,惭愧啊。 = = 但是今天机械键盘到了,有弄好了自行车,好高兴\(^o^)/~

其实也不是看懂,就会套个模板而已。。。。

这题最重要的就是一个:

多组输入一定要写个init()函数清空,并且输入的时候每次都要调用init()

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int INF=0x3f3f3f3f;
typedef long long LL;
#define PI(A) printf("%d\n",A)
#define SI(N) scanf("%d",&(N))
#define SII(N,M) scanf("%d%d",&(N),&(M))
#define cle(a,val) memset(a,(val),sizeof(a))
#define rep(i,b) for(int i=0;i<(b);i++)
#define Rep(i,a,b) for(int i=(a);i<=(b);i++)
#define reRep(i,a,b) for(int i=(a);i>=(b);i--)
const double EPS= 1e-9 ;

/*  /////////////////////////     C o d i n g  S p a c e     /////////////////////////  */

const int MAX_V= 300 + 5 ;

///小白书模板/////////////////

///PS:V(即顶点数)一定要赋值
///PS:以下多组输入,要初始化

struct edge
{
    int to,cap,cost,rev;
};

int V;                  //顶点数
vector<edge> G[MAX_V];//图的邻接表
int dist[MAX_V];      //最短距离
int prevv[MAX_V],preve[MAX_V]; //最短路中的前驱节点和对应的边

//添加边和费用
void add_edge(int from,int to,int cap,int cost)
{
    G[from].push_back((edge)
    {
        to,cap,cost,G[to].size()
    });
    G[to].push_back((edge)
    {
        from,0,-cost,G[from].size()-1
    });
}

//求解从s到t流量为f的最小费用流
//如果不能再增广就返回-1
int min_cost_flow(int s,int t,int f)
{
    int res=0;
    while(f>0)
    {
        fill(dist,dist+V+1,INF);
        dist[s]=0;
        bool updata=true;
        while(updata)
        {
            updata=false;
            for (int v=0; v<V; v++)
            {
                if (dist[v]==INF) continue;

                for(int i=0; i<G[v].size(); i++)
                {
                    edge &e=G[v][i];
                    if (e.cap>0&&dist[e.to]>dist[v]+e.cost)
                    {
                        dist[e.to]=dist[v]+e.cost;
                        prevv[e.to]=v;
                        preve[e.to]=i;
                        updata=true;
                    }
                }
            }
        }

        if (dist[t]==INF)
        {
            //不能在增广
            return -1;
        }
        int d=f;
        for (int v=t; v!=s; v=prevv[v])
        {
            d=min(d,G[prevv[v]][preve[v]].cap);

        }
        f-=d;
        res+=d*dist[t];
        for (int v=t; v!=s; v=prevv[v])
        {
            edge &e=G[prevv[v]][preve[v]];
            e.cap-=d;
            G[v][e.rev].cap+=d;

        }
    }
    return res;
}
///end/////////////////

char ditu[MAX_V][MAX_V];
int N,M;

int main()
{
#ifndef ONLINE_JUDGE
    freopen("C:\\Users\\Zmy\\Desktop\\in.txt","r",stdin);
//    freopen("C:\\Users\\Zmy\\Desktop\\out.txt","w",stdout);
#endif

    while(~SII(N,M),N||M)
    {

        cle(ditu,0);
        rep(i,N)
        {
            scanf("%s",ditu[i]);
        }

        int numm=0;
        rep(i,N)
        rep(j,M)
        if (ditu[i][j]==‘m‘)
        {
            numm++;
        }

        int cntm=1,cntH=numm+1;
        rep(i,N)
        {
            rep(j,M)
            {
                if (ditu[i][j]==‘m‘)
                {
                    cntH=numm+1;
                    rep(i2,N)
                    {
                        rep(j2,M)
                        {
                            if (ditu[i2][j2]==‘H‘)
                            {
                                add_edge(cntm,cntH,1,abs(i-i2)+abs(j-j2));
//                                printf("cntm=%d  cntH=%d\n",cntm,cntH);
//                                printf("cost=%d\n",abs(i-i2)+abs(j-j2));
                                cntH++;

                            }
                        }
                    }
                    cntm++;

                }
            }
        }

        for (int i=1;i<cntm;i++)
        {
            add_edge(0,i,1,0);
//            printf("0->%d\n",i);
        }
        for (int i=numm+1;i<=2*numm;i++)
        {
            add_edge(i,2*numm+1,1,0);
//            printf("%d->%d\n",i,2*numm+1);
        }

    //这的V一定要赋值
        V=2*numm+1;
        /**< 一定要初始化 */
        cle(prevv,0);
        cle(preve,0);

        int ans=min_cost_flow(0,2*numm+1,numm);

        PI(ans);

        /**< 一定要初始化   以后就用一个init都初始化了*/
        for (int i=0;i<MAX_V;i++)
        {
            G[i].clear();
        }

    }

    return 0;
}
时间: 2024-12-28 20:52:57

Going Home (hdu 1533 最小费用流)的相关文章

HDU 1533 Going Home(KM完美匹配)

HDU 1533 Going Home 题目链接 题意:就是一个H要对应一个m,使得总曼哈顿距离最小 思路:KM完美匹配,由于是要最小,所以边权建负数来处理即可 代码: #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int MAXNODE = 105; typedef int Type; const T

POJ 2195 Going Home / HDU 1533(最小费用最大流模板)

题目大意: 有一个最大是100 * 100 的网格图,上面有 s 个 房子和人,人每移动一个格子花费1的代价,求最小代价让所有的人都进入一个房子.每个房子只能进入一个人. 算法讨论: 注意是KM 和 MCMF算法,我写的是MCMF算法,一开始想的是连10000个点,但是不会连那些大众点之间的边,只会连超级点和普通点之间的边.后来觉得只要连房子点和 人点就可以了.连从人到房子的边,容量是1,花费是他们之间的曼哈顿距离,然后超级源点和超级汇点像上面那样连接,注意连点的时候把他们每个点都具体化一下,就

hdu 1533 Going Home (KM算法)

Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2715    Accepted Submission(s): 1366 Problem Description On a grid map there are n little men and n houses. In each unit time, every

【HDU 1533】 Going Home (KM)

Going Home Problem Description On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, either horizontally, or vertically, to an adjacent point. For each little man, you need to pay a $1 travel f

MZL&#39;s City (hdu 5352 最小费用流 ||二分图匹配)

MZL's City Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 719    Accepted Submission(s): 251 Problem Description MZL is an active girl who has her own country. Her big country has N cities num

Going Home HDU - 1533 (费用流)

Going Home HDU - 1533 1 //费用流初探 2 #include <iostream> 3 #include <queue> 4 #include <cstring> 5 #include <cstdio> 6 #include <algorithm> 7 using namespace std; 8 const int inf = 0x3f3f3f3f; 9 const int maxn = 110; 10 char gra

HDU 1533 Going Home(最小费用流)

Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3278    Accepted Submission(s): 1661 Problem Description On a grid map there are n little men and n houses. In each unit time, every

poj 2195//hdu 1533 Going Home 最小费用流(spfa)

Language: Default Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18601   Accepted: 9500 Description On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, either horizon

POJ 2195 &amp; HDU 1533 Going Home(最小费用最大流)

题目链接: POJ:http://poj.org/problem?id=2195 HDU:http://acm.hdu.edu.cn/showproblem.php?pid=1533 Description On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, either horizontally, or vertically,