比较简单的题了。

只需从左上角到右下角找两条路就可以了。

因为每个点只能走一次,所以拆点,限制流量为1。

因为求的是最大值,所以权值取反求最小值。

因为第一个点和最后一个点经过两次,只算一次,最后要减去。

ps:数组还是开大点好。。。。不知道什么时候就SB了。。。

注意汇点可能不是最后一个点(模板的问题。。

注意初始化的范围。。。。

matrix again只是数据大了,算法不用改。。。无聊。。。。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <bitset>
#include <cstdio>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <map>
#include <set>
#define pk(x) printf("%d\n", x)
using namespace std;
#define PI acos(-1.0)
#define EPS 1E-6
#define clr(x,c) memset(x,c,sizeof(x))
//#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll; const int MAXV = ;
const int INF = <<; struct Edge { int to, cap, cost, rev; };
vector<Edge> G[MAXV];
int dist[MAXV], prv[MAXV], pre[MAXV], in[MAXV];
queue<int> que; void addedge(int from, int to, int cap, int cost) {
G[from].push_back((Edge){to, cap, cost, G[to].size()});
G[to].push_back((Edge){from, , -cost, G[from].size()-});
} int min_cost_max_flow(int s, int t) { //, int f) {
int res = ;
int f = ;
while () { //f > 0) {
for (int i = ; i <= t; ++i) dist[i] = INF, in[i] = ;
dist[s] = ;
while (!que.empty()) que.pop();
in[s] = ;
que.push(s); while (!que.empty()) {
int u = que.front(); que.pop(); in[u] = ;
for (int i = ; i < G[u].size(); ++i) {
Edge &e = G[u][i];
if (e.cap > && dist[e.to] > dist[u] + e.cost) {
dist[e.to] = dist[u] + e.cost; prv[e.to] = u;
pre[e.to] = i;
if (in[e.to] == ) {
in[e.to] = ;
que.push(e.to);
}
}
}
} if (dist[t] == INF) break; //return -1; int d = INF; // d = f;
for (int v = t; v != s; v = prv[v]) {
d = min(d, G[prv[v]][pre[v]].cap);
}
f += d;
res += d * dist[t];
for (int v = t; v != s; v = prv[v]) {
Edge &e = G[prv[v]][pre[v]];
e.cap -= d;
G[v][e.rev].cap += d;
}
}
return res;
//return f;
} int n;
int getid1(int x, int y) { return x*n+y+; }
int getid2(int x, int y) { return x*n+y+n*n+; }
int a[][];
int main()
{
while (~scanf("%d", &n)) {
for (int i = ; i < n; ++i) {
for (int j = ; j < n; ++j) {
scanf("%d", &a[i][j]);
}
}
for (int i = ; i <= *n*n; ++i) G[i].clear();
for (int i = ; i < n; ++i) {
for (int j = ; j < n; ++j) {
if (i+j == ) addedge(getid1(i,j), getid2(i,j), , -a[i][j]);
else if (i+j == n* - ) addedge(getid1(i,j), getid2(i, j), , -a[i][j]);
else addedge(getid1(i, j), getid2(i, j), , -a[i][j]);
if (i+<n) addedge(getid2(i, j), getid1(i+, j), , );
if (j+<n) addedge(getid2(i, j), getid1(i, j+), , );
}
}
printf("%d\n", -min_cost_max_flow(getid1(,), getid2(n-,n-)) - a[][] - a[n-][n-]);
}
return ;
}

hdu2686

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <bitset>
#include <cstdio>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <map>
#include <set>
#define pk(x) printf("%d\n", x)
using namespace std;
#define PI acos(-1.0)
#define EPS 1E-6
#define clr(x,c) memset(x,c,sizeof(x))
//#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll; const int MAXV = **+;
const int INF = <<; struct Edge { int to, cap, cost, rev; };
vector<Edge> G[MAXV];
int dist[MAXV], prv[MAXV], pre[MAXV], in[MAXV];
queue<int> que; void addedge(int from, int to, int cap, int cost) {
G[from].push_back((Edge){to, cap, cost, G[to].size()});
G[to].push_back((Edge){from, , -cost, G[from].size()-});
} int min_cost_max_flow(int s, int t) { //, int f) {
int res = ;
int f = ;
while () { //f > 0) {
for (int i = ; i <= t; ++i) dist[i] = INF, in[i] = ;
dist[s] = ;
while (!que.empty()) que.pop();
in[s] = ;
que.push(s); while (!que.empty()) {
int u = que.front(); que.pop(); in[u] = ;
for (int i = ; i < G[u].size(); ++i) {
Edge &e = G[u][i];
if (e.cap > && dist[e.to] > dist[u] + e.cost) {
dist[e.to] = dist[u] + e.cost; prv[e.to] = u;
pre[e.to] = i;
if (in[e.to] == ) {
in[e.to] = ;
que.push(e.to);
}
}
}
} if (dist[t] == INF) break; //return -1; int d = INF; // d = f;
for (int v = t; v != s; v = prv[v]) {
d = min(d, G[prv[v]][pre[v]].cap);
}
f += d;
res += d * dist[t];
for (int v = t; v != s; v = prv[v]) {
Edge &e = G[prv[v]][pre[v]];
e.cap -= d;
G[v][e.rev].cap += d;
}
}
return res;
//return f;
} inline int Scan()
{
char ch = getchar();
int data = ;
while (ch < '' || ch > '') ch = getchar();
do {
data = data* + ch-'';
ch = getchar();
} while (ch >= '' && ch <= '');
return data;
} int n;
int getid1(int x, int y) { return x*n+y+; }
int getid2(int x, int y) { return x*n+y+n*n+; }
int a[][];
int main()
{
while (~scanf("%d", &n)) {
int maxn = *n*n;
for (int i = ; i <= maxn; ++i) G[i].clear();
for (int i = ; i < n; ++i) {
for (int j = ; j < n; ++j) {
a[i][j] = Scan();
if (i+j == || i+j == n*-) addedge(getid1(i,j), getid2(i,j), , -a[i][j]);
else addedge(getid1(i, j), getid2(i, j), , -a[i][j]);
if (i+<n) addedge(getid2(i, j), getid1(i+, j), , );
if (j+<n) addedge(getid2(i, j), getid1(i, j+), , );
}
}
printf("%d\n", -min_cost_max_flow(getid1(,), getid2(n-,n-)) - a[][] - a[n-][n-]);
}
return ;
}

hdu3376

HDU2686-Matrix & HDU3376-Matrix Again(费用流)的更多相关文章

  1. HDU 2686 Matrix 3376 Matrix Again(费用流)

    HDU 2686 Matrix 题目链接 3376 Matrix Again 题目链接 题意:这两题是一样的,仅仅是数据范围不一样,都是一个矩阵,从左上角走到右下角在从右下角走到左上角能得到最大价值 ...

  2. POJ3422 Kaka&#39;s Matrix Travels 【最大费用最大流】

    Kaka's Matrix Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8006   Accepted:  ...

  3. POJ 3422 Kaka&#39;s Matrix Travels(费用流)

    POJ 3422 Kaka's Matrix Travels 题目链接 题意:一个矩阵.从左上角往右下角走k趟,每次走过数字就变成0,而且获得这个数字,要求走完之后,所获得数字之和最大 思路:有点类似 ...

  4. hdoj 3376,2686 Matrix Again 【最小费用最大流】

    题目:hdoj 3376 Matrix Again 题意:给出一个m*n的矩阵,然后从左上角到右下角走两次,每次仅仅能向右或者向下,出了末尾点其它仅仅能走一次,不能交叉,每次走到一个格子拿走这个格子中 ...

  5. POJ 2135 Farm Tour &amp;&amp; HDU 2686 Matrix &amp;&amp; HDU 3376 Matrix Again 费用流求来回最短路

    累了就要写题解,近期总是被虐到没脾气. 来回最短路问题貌似也能够用DP来搞.只是拿费用流还是非常方便的. 能够转化成求满流为2 的最小花费.一般做法为拆点,对于 i 拆为2*i 和 2*i+1.然后连 ...

  6. POJ 3422 Kaka's Matrix Travels (K取方格数:最大费用流)

    题意 给出一个n*n大小的矩阵,要求从左上角走到右下角,每次只能向下走或者向右走并取数,某位置取过数之后就只为数值0,现在求解从左上角到右下角走K次的最大值. 思路 经典的费用流模型:K取方格数. 构 ...

  7. poj 3422 Kaka's Matrix Travels 费用流

    题目链接 给一个n*n的矩阵, 从左上角出发, 走到右下角, 然后在返回左上角,这样算两次. 一共重复k次, 每个格子有值, 问能够取得的最大值是多少, 一个格子的值只能取一次, 取完后变为0. 费用 ...

  8. HDU 3376 费用流 Matrix Again

    题意: 给出一个n × n的矩阵,每个格子中有一个数字代表权值,找出从左上角出发到右下角的两条不相交的路径(起点和终点除外),使得两条路径权值之和最大. 分析: 如果n比较小的话是可以DP的,但是现在 ...

  9. HDU2686 费用流 模板

    Matrix Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  10. POJ 2516 Minimum Cost (费用流)

    题面 Dearboy, a goods victualer, now comes to a big problem, and he needs your help. In his sale area ...

随机推荐

  1. C: 数组形参

    知识这个东西,真是知道的越多就不知道的越多,C/C++这塘水得多深啊,哈哈.看下面3个片段:<一> 1 void fun(char a[100]) { 2         fprintf( ...

  2. cctype头文件(字符处理库)的使用

    C++ 中cctype头文件的使用 头文件cctype(字符处理库)中定义了有关字符判断与处理的库函数,使用前要包含头文件: #include <cctype> using namespa ...

  3. 172. Factorial Trailing Zeroes

    题目: Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in ...

  4. CF339

    C. Xenia and Weights 有1...10k的砝码,在天枰上,左右轮流放置砝码,要求之后左右轮流比另一侧重量要大,要求相邻两次砝码不能相同. 解题报告给出(i,j,k)表示balance ...

  5. Frequent values && Ping pong

    Frequent values 题意是不同颜色区间首尾相接,询问一个区间内同色区间的最长长度. 网上流行的做法,包括翻出来之前POJ的代码也是RMQ做法,对于序列上的每个数,记录该数向左和向右延续的最 ...

  6. Java API ——Arrays类

    1.Arrays类概述 · 针对数组进行操作的工具类. · 提供了排序,查找等功能. 2.成员方法 · public static String toString(int[] a):in[] a可以改 ...

  7. 精选7款绚丽的HTML5和jQuery图片动画特效

    在HTML5出现后,图片就变得更加富有动感了,各种图片动画特效也层出不穷,例如图片播放器.图片导航.3D图片动画等等.本文将精选几款具有代表性的HTML5和jQuery图片动画特效,绚丽的画面.实用的 ...

  8. (转)Redis与Memcached的区别

    如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点: 1 Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储. 2 Redis支持 ...

  9. Android开发之AIDL的使用一--跨应用启动Service

    启动其他App的服务,跨进程启动服务. 与启动本应用的Service一样,使用startService(intent)方法 不同的是intent需要携带的内容不同,需要使用intent的setComp ...

  10. Java之数组array和集合list、set、map

    之前一直分不清楚java中的array,list.同时对set,map,list的用法彻底迷糊,直到看到了这篇文章,讲解的很清楚. 世间上本来没有集合,(只有数组参考C语言)但有人想要,所以有了集合 ...