zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",cntm,cntH);
    //                                printf("cost=%d
    ",abs(i-i2)+abs(j-j2));
                                    cntH++;
    
                                }
                            }
                        }
                        cntm++;
    
                    }
                }
            }
    
            for (int i=1;i<cntm;i++)
            {
                add_edge(0,i,1,0);
    //            printf("0->%d
    ",i);
            }
            for (int i=numm+1;i<=2*numm;i++)
            {
                add_edge(i,2*numm+1,1,0);
    //            printf("%d->%d
    ",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; }
  • 相关阅读:
    ASP 调用dll(VB)及封装dll实例
    C#中的Dictionary简介
    C#中Dictionary、ArrayList、Hashtable和Array的区别
    类 Array Arraylist List Hashtable Dictionary
    利用ASP.NET AJAX的Timer讓GridView每隔一段時間做到自動換頁的功能
    nvmw install 失败. 需修改"Msxml2.XMLHTTP"为"Msxml2.ServerXMLHTTP"
    cyark
    [001] winnie the pooh
    把你的英语用起来-七天行动-置之死的而后生
    安卓模拟器还是"genymotion"最靠谱.
  • 原文地址:https://www.cnblogs.com/s1124yy/p/5658572.html
Copyright © 2011-2022 走看看