• hdu-3376-Matrix Again(最小费用最大流)


    题意:

    给一个矩形,从左上角走到右下角,并返回左上角(一个单元格只能走一次,左上角和右下角两个点除外)

    并且从左上到右下只能往右和下两个方向。从右下返回左上只能走上和左两个方向!

    分析:

    拆点,最小费用最大流

    。。

    额。。。刘汝佳训练指南的最小费用最大流模板超时了。。。。。。。。。。。。。。。。。。

    可能是因为边太少,点太多的缘故吧!还是数组实现的邻接表可靠啊!!!

    // File Name: 3376.cpp
    // Author: Zlbing
    // Created Time: 2013年08月15日 星期四 13时24分37秒
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define LL long long
    #define REP(i,r,n) for(int i=r;i<=n;i++)
    #define RREP(i,n,r) for(int i=n;i>=r;i--)
    /*
    const int MAXN=720010;
    
    struct Edge{
        int from,to,cap,flow,cost;
    };
    struct MCMF{
        int n,m,s,t;
        vector<Edge>edges;
        vector<int> G[MAXN];
        int inq[MAXN];
        int d[MAXN];
        int p[MAXN];
        int a[MAXN];
        void init(int n){
            this->n=n;
            for(int i=0;i<=n;i++)G[i].clear();
            edges.clear();
        }
        void AddEdge(int from,int to,int cap,int cost){
            Edge e;
            e.from=from,e.to=to,e.cap=cap,e.flow=0,e.cost=cost;
            edges.push_back(e);
            //edges.push_back((Edge){from,to,cap,0,cost});
            e.from=to,e.to=from,e.cap=0,e.flow=0,e.cost=-cost;
            //edges.push_back((Edge){to,from,0,0,-cost});
            edges.push_back(e);
            m=edges.size();
            G[from].push_back(m-2);
            G[to].push_back(m-1);
        }
        bool BellmanFord(int s,int t,int& flow,int& cost){
            for(int i=0;i<=n;i++)d[i]=INF;
                CL(inq,0);
            d[s]=0;inq[s]=1;p[s]=0;a[s]=INF;
    
            queue<int>Q;
            Q.push(s);
            while(!Q.empty()){
                int u=Q.front();Q.pop();
                inq[u]=0;
                for(int i=0;i<(int)G[u].size();i++){
                    Edge& e=edges[G[u][i]];
                    if(e.cap>e.flow&&d[e.to]>d[u]+e.cost){
                        d[e.to]=d[u]+e.cost;
                        p[e.to]=G[u][i];
                        a[e.to]=min(a[u],e.cap-e.flow);
                        if(!inq[e.to]){
                            Q.push(e.to);
                            inq[e.to]=1;
                        }
                    }
                }
            }
            if(d[t]==INF)return false;
            flow+=a[t];
            cost+=d[t]*a[t];
            int u=t;
            while(u!=s){
                edges[p[u]].flow+=a[t];
                edges[p[u]^1].flow-=a[t];
                u=edges[p[u]].from;
            }
            return true;
        }
        int Mincost(int s,int t){
            int flow=0,cost=0;
            while(BellmanFord(s,t,flow,cost));
            return cost;
        }
    };
    MCMF solver;
    */
    int sumFlow;
    const int MAXN = 720010;
    const int MAXM = 1000010;
    struct Edge
    {
        int u, v, cap, cost;
        int next;
    }edge[MAXM<<2];
    int NE;
    int head[MAXN], dist[MAXN], pp[MAXN];
    bool vis[MAXN];
    void init()
    {
        NE = 0;
        memset(head, -1, sizeof(head));
    }
    void addedge(int u, int v, int cap, int cost)
    {
        edge[NE].u = u; edge[NE].v = v; edge[NE].cap = cap; edge[NE].cost = cost;
        edge[NE].next = head[u]; head[u] = NE++;
        edge[NE].u = v; edge[NE].v = u; edge[NE].cap = 0; edge[NE].cost = -cost;
        edge[NE].next = head[v]; head[v] = NE++;
    }
    bool SPFA(int s, int t, int n)
    {
        int i, u, v;
        queue <int> qu;
        memset(vis,false,sizeof(vis));
        memset(pp,-1,sizeof(pp));
        for(i = 0; i <= n; i++) dist[i] = INF;
        vis[s] = true; dist[s] = 0;
        qu.push(s);
        while(!qu.empty())
        {
            u = qu.front(); qu.pop(); vis[u] = false;
            for(i = head[u]; i != -1; i = edge[i].next)
            {
                v = edge[i].v;
                if(edge[i].cap && dist[v] > dist[u] + edge[i].cost)
                {
                    dist[v] = dist[u] + edge[i].cost;
                    pp[v] = i;
                    if(!vis[v])
                    {
                        qu.push(v);
                        vis[v] = true;
                    }
                }
            }
        }
        if(dist[t] == INF) return false;
        return true;
    }
    int MCMF(int s, int t, int n) // minCostMaxFlow
    {
        int flow = 0; // 总流量
        int i, minflow, mincost;
        mincost = 0;
        while(SPFA(s, t, n))
        {
            minflow = INF + 1;
            for(i = pp[t]; i != -1; i = pp[edge[i].u])
                if(edge[i].cap < minflow)
                    minflow = edge[i].cap;
            flow += minflow;
            for(i = pp[t]; i != -1; i = pp[edge[i].u])
            {
                edge[i].cap -= minflow;
                edge[i^1].cap += minflow;
            }
            mincost += dist[t] * minflow;
        }
        sumFlow = flow; // 题目需要流量,用于判断
        return mincost;
    }
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            //solver.init(n*n*2+5);
            init();
            int a;
            int s=0;
            int t=((n-1)*n+n-1)*2+1;
            REP(i,0,n-1)
                REP(j,0,n-1){
                    scanf("%d",&a);
                    //solver.AddEdge((i*n+j)*2,(i*n+j)*2+1,1,-a);
                    addedge((i*n+j)*2,(i*n+j)*2+1,1,-a);
                    if(i!=n-1)
                    {
                        //solver.AddEdge((i*n+j)*2+1,((i+1)*n+j)*2,1,0);
                        addedge((i*n+j)*2+1,((i+1)*n+j)*2,1,0);
                    }
                    if(j!=n-1)
                    {
                        //solver.AddEdge((i*n+j)*2+1,(i*n+j+1)*2,1,0);
                        addedge((i*n+j)*2+1,(i*n+j+1)*2,1,0);
                    }
                }
            addedge(s,s+1,1,0);
            addedge(t-1,t,1,0);
            int ans=-MCMF(s,t,t);
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    516. Longest Palindromic Subsequence
    31. Next Permutation
    572. Subtree of Another Tree
    vue中无法监听到子组件的事件的问题
    vue中注意watch的执行顺序
    vue中路由懒加载浅析
    关于typescript 报错问题
    深入理解Typescript中文版
    vue中的高阶组件
    vue中的mixins
  • 原文地址:https://www.cnblogs.com/arbitrary/p/3262109.html
Copyright © 2020-2023  润新知