• HDU 2686 Matrix(最大费用最大流+拆点)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2686

    POJ3422一样

    删掉K把汇点与源点的容量改为2(由于有两个方向的选择)就可以

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    const int maxn = 20000;
    const int maxm = 800000;
    const int inf = 1e8;
    const int INF = 0x3f3f3f3f;
    #define MIN INT_MIN
    #define MAX 1e6
    #define LL long long
    #define init(a) memset(a,0,sizeof(a))
    #define FOR(i,a,b) for(int i = a;i<b;i++)
    #define max(a,b) (a>b)?(a):(b)
    #define min(a,b) (a>b)?(b):(a)
    using namespace std;
    struct node
    {
        int u,v,w,cap,next;
    } edge[maxm];
    int pre[maxn],dis[maxn],head[maxn],cnt;
    bool vis[maxn];
    int n;
    void add(int u,int v,int c,int cap)
    {
        edge[cnt].u=u;
        edge[cnt].v=v;
        edge[cnt].w=c;
        edge[cnt].cap=cap;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    
        edge[cnt].u=v;
        edge[cnt].v=u;
        edge[cnt].w=-c;
        edge[cnt].cap=0;
        edge[cnt].next=head[v];
        head[v]=cnt++;
    }
    int spfa(int s,int t)
    {
        queue<int>q;
        while(q.empty()==false) q.pop();
        q.push(s);
        memset(vis,0,sizeof(vis));
        memset(pre,-1,sizeof(pre));
        FOR(i,s,t+1)
        dis[i] = -1;//求最长路dis数组初始化为-1
    
        dis[s]=0;
        vis[s] = 1;
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            vis[u] = 0;
            for(int i=head[u]; i!=-1; i=edge[i].next)
            {
                if(edge[i].cap && dis[edge[i].v] < (dis[u]+edge[i].w))//求最长路
                {
                    dis[edge[i].v] = dis[u]+edge[i].w;
                    pre[edge[i].v] = i;
                    if(!vis[edge[i].v])
                    {
                        vis[edge[i].v]=1;
                        q.push(edge[i].v);
                    }
                }
            }
    
        }
        if(dis[t] != -1)//------------------忘改了。

    return 1; else return 0; } int MinCostMaxFlow(int s,int t) { int flow=0,cost=0; while(spfa(s,t)) { int df = inf; for(int i = pre[t]; i!=-1; i=pre[edge[i].u]) { if(edge[i].cap<df) df = edge[i].cap; } flow += df; for(int i=pre[t]; i!=-1; i=pre[edge[i].u]) { edge[i].cap -= df; edge[i^1].cap += df; } //printf("df = %d ",df); cost += dis[t] * df; } return cost; } void initt() { cnt=0; memset(head,-1,sizeof(head)); } int ma; int main() { int s,t,k; while(~scanf("%d",&n)) { initt(); s = 0; t=2*n*n+1; add(s,1,0,2); int num = n*n; FOR(i,1,n+1) { FOR(j,1,n+1) { scanf("%d",&ma); add((i-1)*n+j,(i-1)*n+j+num,ma,1); add((i-1)*n+j,(i-1)*n+j+num,0,1);//本点与拆点连线,费用0。容量为无穷 if(i<=n-1)//向下建图 { add((i-1)*n+j+num,i*n+j,0,1); } if(j<=n-1)//向右建图 { add((i-1)*n+j+num,(i-1)*n+j+1,0,1); } } } add(t-1,t,0,2); int ans = MinCostMaxFlow(s,t); printf("%d ",ans); } return 0; }



  • 相关阅读:
    SQL SERVER中一些常见性能问题的总结
    【BZOJ2554】Color 概率神题
    【BZOJ1818】[Cqoi2010]内部白点 扫描线+树状数组
    【BZOJ1879】[Sdoi2009]Bill的挑战 状压DP
    【BZOJ2668】[cqoi2012]交换棋子 费用流
    【BZOJ4372】烁烁的游戏 动态树分治+线段树
    【BZOJ3470】Freda’s Walk 概率与期望
    【BZOJ2087】[Poi2010]Sheep 几何+DP
    【BZOJ4428】[Nwerc2015]Debugging调试 记忆化搜索+分块
    【BZOJ2137】submultiple 高斯消元求伯努利数
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6959031.html
Copyright © 2020-2023  润新知