Matrix

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2350    Accepted Submission(s): 1241

Problem Description
Yifenfei very like play a number game in the n*n Matrix. A positive integer number is put in each area of the Matrix.
Every
time yifenfei should to do is that choose a detour which frome the top
left point to the bottom right point and than back to the top left point
with the maximal values of sum integers that area of Matrix yifenfei
choose. But from the top to the bottom can only choose right and down,
from the bottom to the top can only choose left and up. And yifenfei can
not pass the same area of the Matrix except the start and end.
 
Input
The input contains multiple test cases.
Each case first line given the integer n (2<n<30)
Than n lines,each line include n positive integers.(<100)
 
Output
For each test case output the maximal values yifenfei can get.
 
Sample Input
2
10 3
5 10
3
10 3 3
2 5 3
6 7 10
5
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
 
Sample Output
28
46
80
 
Author
yifenfei
 
Source
 
题意:一个人要从(1,1)->(n,n) 然后要从(n,n)->(1,1),每个点最多走一次,每个点都要一个权值,问这样走完之后能够得到的最大权值是多少?
题解:由于每个点只能够走一次,所以我们将除了 (1,1)和(n,n) 之外的点都拆点来限制次数(其实好像(n,n)也可以拆,因为也只会走一次,但是(1,1)是不能够拆的),然后将(i-1)*n+j向(i-1)+j+n*n连一条容量为1,费用为 -graph[i][j] ,然后将每个点都和其右边和下面的点连一条容量为1,费用为 0的边,然后建立超级源点,向 (1,1)连一条容量为2,费用为0的边,建立超级汇点,然后将(n,n)向超级汇点连一条容量为2,费用为0的边,这样就达到了限制次数为2的效果,最后跑一遍最小费用最大流,取反之后加上graph[1][1]和graph[n][n]即最后的结果.
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int INF = ;
const int N = ;
const int M = ;
struct Edge{
int u,v,cap,cost,next;
}edge[M];
int head[N],tot,low[N],pre[N];
int total ;
bool vis[N];
int flag[N][N];
void addEdge(int u,int v,int cap,int cost,int &k){
edge[k].u=u,edge[k].v=v,edge[k].cap = cap,edge[k].cost = cost,edge[k].next = head[u],head[u] = k++;
edge[k].u=v,edge[k].v=u,edge[k].cap = ,edge[k].cost = -cost,edge[k].next = head[v],head[v] = k++;
}
void init(){
memset(head,-,sizeof(head));
tot = ;
}
bool spfa(int s,int t,int n){
memset(vis,false,sizeof(vis));
for(int i=;i<=n;i++){
low[i] = INF;
pre[i] = -;
}
queue<int> q;
low[s] = ;
q.push(s);
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = false;
for(int k=head[u];k!=-;k=edge[k].next){
int v = edge[k].v;
if(edge[k].cap>&&low[v]>low[u]+edge[k].cost){
low[v] = low[u] + edge[k].cost;
pre[v] = k; ///v为终点对应的边
if(!vis[v]){
vis[v] = true;
q.push(v);
}
}
}
}
if(pre[t]==-) return false;
return true;
}
int MCMF(int s,int t,int n){
int mincost = ,minflow,flow=;
while(spfa(s,t,n))
{
minflow=INF+;
for(int i=pre[t];i!=-;i=pre[edge[i].u])
minflow=min(minflow,edge[i].cap);
flow+=minflow;
for(int i=pre[t];i!=-;i=pre[edge[i].u])
{
edge[i].cap-=minflow;
edge[i^].cap+=minflow;
}
mincost+=low[t]*minflow;
}
total=flow;
return mincost;
}
int n;
int graph[][];
int P(int x,int y){
return (x-)*n+y;
}
int main(){
while(scanf("%d",&n)!=EOF){
init();
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
scanf("%d",&graph[i][j]);
}
}
int src = ,des = *n*n+;
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
if(P(i,j)!=&&P(i,j)!=n*n){
addEdge(P(i,j),P(i,j)+n*n,,-graph[i][j],tot);
if(i!=n) addEdge(P(i,j)+n*n,P(i+,j),,,tot);
if(j!=n) addEdge(P(i,j)+n*n,P(i,j)+,,,tot);
}else{
if(P(i,j)==){
addEdge(P(i,j),P(i+,j),,,tot);
addEdge(P(i,j),P(i,j)+,,,tot);
}
}
}
}
addEdge(src,,,,tot);
addEdge(n*n,des,,,tot);
int min_cost = MCMF(src,des,*n*n+);
printf("%d\n",-min_cost+graph[][]+graph[n][n]);
}
}

hdu 3376开大一点就OK

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int INF = ;
const int N = ;
const int M = ;
struct Edge{
int u,v,cap,cost,next;
}edge[M];
int head[N],tot,low[N],pre[N];
int total ;
bool vis[N];
void addEdge(int u,int v,int cap,int cost,int &k){
edge[k].u=u,edge[k].v=v,edge[k].cap = cap,edge[k].cost = cost,edge[k].next = head[u],head[u] = k++;
edge[k].u=v,edge[k].v=u,edge[k].cap = ,edge[k].cost = -cost,edge[k].next = head[v],head[v] = k++;
}
void init(){
memset(head,-,sizeof(head));
tot = ;
}
bool spfa(int s,int t,int n){
memset(vis,false,sizeof(vis));
for(int i=;i<=n;i++){
low[i] = INF;
pre[i] = -;
}
queue<int> q;
low[s] = ;
q.push(s);
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = false;
for(int k=head[u];k!=-;k=edge[k].next){
int v = edge[k].v;
if(edge[k].cap>&&low[v]>low[u]+edge[k].cost){
low[v] = low[u] + edge[k].cost;
pre[v] = k; ///v为终点对应的边
if(!vis[v]){
vis[v] = true;
q.push(v);
}
}
}
}
if(pre[t]==-) return false;
return true;
}
int MCMF(int s,int t,int n){
int mincost = ,minflow,flow=;
while(spfa(s,t,n))
{
minflow=INF+;
for(int i=pre[t];i!=-;i=pre[edge[i].u])
minflow=min(minflow,edge[i].cap);
flow+=minflow;
for(int i=pre[t];i!=-;i=pre[edge[i].u])
{
edge[i].cap-=minflow;
edge[i^].cap+=minflow;
}
mincost+=low[t]*minflow;
}
total=flow;
return mincost;
}
int n;
int graph[][];
int P(int x,int y){
return (x-)*n+y;
}
int main(){
while(scanf("%d",&n)!=EOF){
init();
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
scanf("%d",&graph[i][j]);
}
}
int src = ,des = *n*n+;
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
if(P(i,j)!=&&P(i,j)!=n*n){
addEdge(P(i,j),P(i,j)+n*n,,-graph[i][j],tot);
if(i!=n) addEdge(P(i,j)+n*n,P(i+,j),,,tot);
if(j!=n) addEdge(P(i,j)+n*n,P(i,j)+,,,tot);
}else{
if(P(i,j)==){
addEdge(P(i,j),P(i+,j),,,tot);
addEdge(P(i,j),P(i,j)+,,,tot);
}
}
}
}
addEdge(src,,,,tot);
addEdge(n*n,des,,,tot);
int min_cost = MCMF(src,des,*n*n+);
printf("%d\n",-min_cost+graph[][]+graph[n][n]);
}
}

hdu 2686&&hdu 3376(拆点+构图+最小费用最大流)的更多相关文章

  1. hdu 4411 2012杭州赛区网络赛 最小费用最大流 ***

    题意: 有 n+1 个城市编号 0..n,有 m 条无向边,在 0 城市有个警察总部,最多可以派出 k 个逮捕队伍,在1..n 每个城市有一个犯罪团伙,          每个逮捕队伍在每个城市可以选 ...

  2. HDU 6118 度度熊的交易计划(最小费用最大流)

    Problem Description度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题: 喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区. 由于生产能力的区别,第i个 ...

  3. HDU 3435 A new Graph Game(最小费用最大流)&amp;HDU 3488

    A new Graph Game Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. hdu 3488(KM算法||最小费用最大流)

    Tour Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submis ...

  5. hdu-3376-Matrix Again(最小费用最大流)

    题意: 给一个矩形,从左上角走到右下角,并返回左上角(一个单元格只能走一次,左上角和右下角两个点除外) 并且从左上到右下只能往右和下两个方向.从右下返回左上只能走上和左两个方向! 分析: 拆点,最小费 ...

  6. hdu 2686 Matrix 最小费用最大流

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2686 Yifenfei very like play a number game in the n*n ...

  7. hdu 4494 Teamwork 最小费用最大流

    Teamwork Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4494 ...

  8. hdu 1533 Going Home 最小费用最大流

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1533 On a grid map there are n little men and n house ...

  9. HDU 5988.Coding Contest 最小费用最大流

    Coding Contest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

随机推荐

  1. 多线程中Local Store Slot(本地存储槽)[转]

    1. 使用ThreadStatic特性 ThreadStatic特性是最简单的TLS使用,且只支持静态字段,只需要在字段上标记这个特性就可以了: [ThreadStatic]   static str ...

  2. 差点AFO

    差点就AFO了,小伙伴们一定注意护眼啊. 眼睛总算是活过来了. 还有一个月联赛,加油

  3. 怎样才能快速成为JavaScript高手

    如何快速成为JavaScript高手?之前我拿这个问题问过我的同事,也问过国内的一些JavaScript高手. 最近,我一直在拿这个问题问自己.之所以会有这个问题,我基于两个前提:第一.我自认为自己不 ...

  4. Wireshark中TCP segment of a reassembled PDU的含义

    By francis_hao    Sep 16,2017   在用Wireshark抓包的时候,经常会看到TCP segment of a reassembled PDU,字面意思是要重组的协议数据 ...

  5. 关于xml文件头部xmlsn

    样本: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://ww ...

  6. HDU4738:Caocao's Bridges(求桥)

    Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. find_in_set 函数使用方法

    find_in_set 函数使用方法 个例子来说: 有个文章表里面有个type字段,它存储的是文章类型,有 1头条.2推荐.3热点.4图文...1,12,13 等等 . 现在有篇文章他既是 头条,又是 ...

  8. bzoj 1568 [JSOI2008]Blue Mary开公司 超哥线段树

    [JSOI2008]Blue Mary开公司 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1808  Solved: 639[Submit][Sta ...

  9. bzoj 1468 Tree 点分

    Tree Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1972  Solved: 1101[Submit][Status][Discuss] Desc ...

  10. Maven命令创建java项目

    ------------------------------java项目搭建--------------------------- 使用Maven构建一个简单的Java项目 1.进入命令行,执行下面的 ...