zoukankan      html  css  js  c++  java
  • POJ 3422 Kaka's Matrix Travels(最小费用最大流)

    http://poj.org/problem?id=3422

    题意 : 给你一个N*N的方格,每个格子有一个数字,让你从左上角开始走,只能往下往右走,走过的数字变为0,走K次,问最大能是多大,累加的。

    思路 :http://blog.csdn.net/qq172108805/article/details/7857503,这道题挺难的,我也是看的题解。

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <queue>
    #include <stdlib.h>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 5050 ;
    const int INF = 1000000000 ;
    const int maxm = 110000 ;
    
    struct node
    {
        int u,v,c,f,b,next ;
    }map[maxm] ;
    bool flag[maxn] ;
    int cap[55][55],dist[maxn],pre[maxn],head[maxn] ;
    int s,t,n,k,ans,cnt ;
    int del,val ;
    
    void addedge(int u,int v,int c,int b)
    {
        map[cnt].u = u ;
        map[cnt].v = v ;
        map[cnt].c = c ;
        map[cnt].b = b ;
        map[cnt].f = 0 ;
        map[cnt].next = head[u] ;
        head[u] = cnt++ ;
    
        map[cnt].u = v ;
        map[cnt].v = u ;
        map[cnt].c = 0 ;
        map[cnt].b = -b ;
        map[cnt].f = 0 ;
        map[cnt].next = head[v] ;
        head[v] = cnt++ ;
    }
    
    void spfa()
    {
        memset(flag,0,sizeof(flag)) ;
        queue<int >Q ;
        Q.push(s) ;
        flag[s] = true ;
        while(!Q.empty())
        {
            int x = Q.front() ;
            Q.pop() ;
            flag[x] = false ;
            for(int i = head[x] ; i+1 ; i = map[i].next)
            {
                int y = map[i].v ;
                if(map[i].c > map[i].f && dist[y] < dist[x] + map[i].b)
                {
                    dist[y] = dist[x]+map[i].b ;
                    pre[y] = i ;
                    if(!flag[y])
                    {
                        flag[y] = true ;
                        Q.push(y) ;
                    }
                }
            }
        }
    }
    
    void mcmf()
    {
        for( ; ; )
        {
            memset(dist,-1,sizeof(dist)) ;
            memset(pre,-1,sizeof(pre)) ;
            dist[s] = 0 ;
            spfa() ;
            if(dist[t] == -1)
            break ;
            int minn = INF ;
            for(int i = pre[t] ; i+1 ; i = pre[map[i].u])
            minn = min(minn,map[i].c-map[i].f) ;
            for(int i = pre[t] ; i+1 ; i = pre[map[i].u])
            {
                map[i].f += minn ;
                map[i^1].f -= minn ;
            }
            ans += dist[t] ;
        }
    }
    
    void Init()
    {
        cnt = 0 ;
        memset(head,-1,sizeof(head)) ;
        s = 0 ;
        t = 2*n*n+1 ;
        del = n*n ;
        ans = 0 ;
    }
    int main()
    {
        scanf("%d %d",&n,&k) ;
        Init() ;
        for(int i = 1 ; i <= n ; i++)
        {
            for(int j = 1 ; j <= n ; j++)
            scanf("%d",&cap[i][j]) ;
        }
        addedge(s,1,k,0) ;
        addedge(n*n+del,t,k,0) ;
        for(int i = 1 ; i <= n ; i++)
        {
            for(int j = 1 ; j <= n ; j++)
            {
                val = (i-1)*n+j ;
                addedge(val,val+del,1,cap[i][j]) ;
                addedge(val,val+del,INF,0) ;
                if(j != n) addedge(val+del,val+1,INF,0) ;
                if(i < n) addedge(val+del,val+n,INF,0) ;
            }
        }
        mcmf() ;
        printf("%d
    ",ans) ;
        return 0;
    }
    View Code
  • 相关阅读:
    Windows 下安装 Python + Django
    asp.net core 一个中小型项目实战的起手式——Swagger配置
    asp.net core 一个中小型项目实战的起手式——项目搭建与仓储模式下的持久层创建(1)
    c#一些常用知识点
    ADO.NET中的5个主要对象
    JavaScript的闭包特性如何给循环中的对象添加事件(一)
    在什么情况下会用到虚方法?它与接口有什么不同?
    一般处理程序Session
    什么是code-Behind技术?
    什么是事务?
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3544711.html
Copyright © 2011-2022 走看看