码迷,mamicode.com
首页 > 其他好文 > 详细

Going Home (hdu 1533 最小费用流)

时间:2016-07-10 23:06:55      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:

集训的图论都快结束了,我才看懂了最小费用流,惭愧啊。 = = 但是今天机械键盘到了,有弄好了自行车,好高兴\(^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; }

Going Home (hdu 1533 最小费用流)

标签:

原文地址:http://www.cnblogs.com/s1124yy/p/5658572.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!