zoukankan      html  css  js  c++  java
  • poj 3422 洛谷P2045 K取方格数(方格取数加强版)

    Description:

       给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该格子的数就变成0,这样一共走K次,现在要求K次所达到的方格的数的和最大

    Input:

      第一行两个数n,k(1<=n<=50, 0<=k<=10)

      接下来n行,每行n个数,分别表示矩阵的每个格子的数

    Output:

      一个数,为最大和

    思路:仍旧是拆点 因为每个点都有一个限制K和一个价值V 所以将一个点拆成两个点,对相邻的点连两条边,一条费用为V,限制为1, 一条费用为0,限制为K - 1。然后跑个最大费用最大流即可

    #include<iostream>
    #include<cstring>
    #include<queue> 
    using namespace std;
    const int N = 50100, M = 2000100;
    int d[N], incf[N], pre[N], n, k, s, t, maxflow, ans;
    bool vis[N];
    
    int head[N],now;
    struct edges{
        int to,next,lim,w;
    }edge[N<<1];
    void add(int x,int y,int z,int c){
        edge[++now] = {y,head[x],z,c};
        head[x] = now;
        edge[++now] = {x,head[y],0,-c};
        head[y] = now;
    }
    
    int id(int i,int j,int k){    return (i - 1)*n + j + k * n * n;}
    
    bool spfa(){
        queue<int> q;
        memset(d,0xcf,sizeof(d));
        memset(vis,0,sizeof(vis));
        q.push(s); d[s] = 0; vis[s] = 1;
        incf[s] = 1e9;
        while(!q.empty()){
            int x = q.front(); vis[x] = 0; q.pop();
            for(int i = head[x]; i; i = edge[i].next){
                int v = edge[i].to;
                if(!edge[i].lim) continue;
                if(d[v] < d[x] + edge[i].w){
                    d[v] = d[x] + edge[i].w;
                    incf[v] = min(incf[x], edge[i].lim);
                    pre[v] = i;
                    if(!vis[v]) vis[v] = 1, q.push(v);
                }
            }
        }
        if(d[t] == 0xcfcfcfcf) return 0;
        return 1;
    }
    void update(){
        int x = t;
        while(x != s){
            int i = pre[x];
            edge[i].lim -= incf[t];
            edge[i ^ 1].lim += incf[t];
            x = edge[i ^ 1].to;
        }
        maxflow += incf[t];
        ans += d[t] * incf[t];
    }
    int main(){
        ios::sync_with_stdio(false);
        cin>>n>>k;
        s = 1, t = 2*n*n;
        now = 1;
        int x;
        for(int i = 1; i <= n; i++)
          for(int j = 1; j <= n; j++){
            cin>>x;
            add(id(i,j,0),id(i,j,1),1,x);
            add(id(i,j,0),id(i,j,1),k - 1,0);
            if(j < n) add(id(i,j,1),id(i,j+1,0),k,0);
            if(i < n) add(id(i,j,1),id(i+1,j,0),k,0);
          }
        while(spfa())
         update();
        cout<<ans<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    【VUE3.0体验】关于路由的一些坑
    TensorFlow中的卷积函数
    TensorFlow源码安装
    ubuntu远程桌面
    TensorFlow图像处理API
    C程序员眼里的Python
    深度剖析HashMap的数据存储实现原理(看完必懂篇)
    golang 互斥锁和读写锁
    golang goroutine的调度
    golang channel的使用以及调度原理
  • 原文地址:https://www.cnblogs.com/Rorshach/p/8684541.html
Copyright © 2011-2022 走看看