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

    POJ 3422 Kaka's Matrix Travels

    题目链接

    题意:一个矩阵。从左上角往右下角走k趟,每次走过数字就变成0,而且获得这个数字,要求走完之后,所获得数字之和最大

    思路:有点类似区间k覆盖的建图方法,把点拆了,每一个点有值的仅仅能选一次,其它都是无值的。利用费用流,入点出点之间连一条容量1,有费用的边,和一条容量k - 1,费用0的边,然后其它就每一个点和右边和下边2个点连边。然后跑费用流

    代码:

    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <queue>
    #include <algorithm>
    using namespace std;
    
    const int MAXNODE = 5005;
    const int MAXEDGE = 100005;
    typedef int Type;
    const Type INF = 0x3f3f3f3f;
    
    struct Edge {
    	int u, v;
    	Type cap, flow, cost;
    	Edge() {}
    	Edge(int u, int v, Type cap, Type flow, Type cost) {
    		this->u = u;
    		this->v = v;
    		this->cap = cap;
    		this->flow = flow;
    		this->cost = cost;
    	}
    };
    
    struct MCFC {
    	int n, m, s, t;
    	Edge edges[MAXEDGE];
    	int first[MAXNODE];
    	int next[MAXEDGE];
    	int inq[MAXNODE];
    	Type d[MAXNODE];
    	int p[MAXNODE];
    	Type a[MAXNODE];
    
    	void init(int n) {
    		this->n = n;
    		memset(first, -1, sizeof(first));
    		m = 0;
    	}
    
    	void add_Edge(int u, int v, Type cap, Type cost) {
    		edges[m] = Edge(u, v, cap, 0, cost);
    		next[m] = first[u];
    		first[u] = m++;
    		edges[m] = Edge(v, u, 0, 0, -cost);
    		next[m] = first[v];
    		first[v] = m++;
    	}
    
    	bool bellmanford(int s, int t, Type &flow, Type &cost) {
    
    		for (int i = 0; i < n; i++) d[i] = INF;
    		memset(inq, false, sizeof(inq));
    		d[s] = 0; inq[s] = true; p[s] = s; a[s] = INF;
    		queue<int> Q;
    		Q.push(s);
    		while (!Q.empty()) {
    			int u = Q.front(); Q.pop();
    			inq[u] = false;
    			for (int i = first[u]; i != -1; i = next[i]) {
    				Edge& e = edges[i];
    				if (e.cap > e.flow && d[e.v] > d[u] + e.cost) {
    					d[e.v] = d[u] + e.cost;
    					p[e.v] = i;
    					a[e.v] = min(a[u], e.cap - e.flow);
    					if (!inq[e.v]) {Q.push(e.v); inq[e.v] = true;}
    				}
    			}
    		}
    		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]].u;
    		}
    		return true;
    	}
    
    	Type Mincost(int s, int t) {
    		Type flow = 0, cost = 0;
    		while (bellmanford(s, t, flow, cost));
    		return cost;
    	}
    } gao;
    
    const int N = 55;
    const int d[2][2] = {0, 1, 1, 0};
    
    int n, k, g[N][N];
    
    int main() {
    	while (~scanf("%d%d", &n, &k)) {
    		gao.init(n * n * 2);
    		for (int i = 0; i < n; i++)
    			for (int j = 0; j < n; j++) {
    				scanf("%d", &g[i][j]);
    				gao.add_Edge(i * n + j, i * n + j + n * n, k - 1, 0);
    				gao.add_Edge(i * n + j, i * n + j + n * n, 1, -g[i][j]);
    			}
    		for (int i = 0; i < n; i++) {
    			for (int j = 0; j < n; j++) {
    				for (int a = 0; a < 2; a++) {
    					int x = i + d[a][0];
    					int y = j + d[a][1];
    					if (x < 0 || x >= n || y < 0 || y >= n) continue;
    					int u = i * n + j, v = x * n + y;
    					gao.add_Edge(u + n * n, v, k - 1, 0);
    				}
    			}
    		}
    		printf("%d
    ", -gao.Mincost(0, n * n * 2 - 1));
    	}
    	return 0;
    }


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    TextBox 只有下划线
    can't find web control library(web控件库)
    DropDownListSalesAC”有一个无效 SelectedValue,因为它不在项目列表中。
    IDE、SATA、SCSI、SAS、FC、SSD 硬盘类型
    如何打印1px表格
    CSS控制打印 分页
    Virtual Server could not open its emulated Ethernet switch driver. To fix this problem, reenable the Virtual Server Emulated Et
    Xml中SelectSingleNode方法中的xpath用法
    热带水果莫入冰箱?水果存放冰箱大法
    探索Asp.net的Postback机制
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4730023.html
Copyright © 2011-2022 走看看