首页 > 代码库 > hdu 2686 Matrix【最大费用流】
hdu 2686 Matrix【最大费用流】
Matrix
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1792 Accepted Submission(s): 958
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.
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)
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
分析:题意是给出一个矩阵,从(0,0)点到(n-1,n-1)点到(0,0)点使这条路径节点权值之和最大,且从(0,0)到(n-1,n-1)点
只能往右或下走,而回路则相反,每个节点只能走一次。因为每个节点走一次,所以要拆点,容量为1,花费为0,前一部分与s连接,后一部分与
t连接。另外还有方向的规则,我们可以这样想:从s-t-s,这一圈相当于跑两遍s-t,只不过多跑了一个s节点和t节点,最后减去即可,如果这样
那我们建边时指、只向每个节点右和下建,因为我们只是从s-t,而所谓的t-s只能向左和上跑,等价与s-t向右和下跑,这样就差不多解决了。
跑最大费流模版可以直接写最小费用流的,只要加边时把cost改成-cost,在把costflow改成-costflow就可以了。
代码示例:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
#define Min(a,b) a<b?a:b
#define maxn 40000+10
#define maxm 20000+10
#define inf 0xffffff
using namespace std;
typedef struct
{
int from,to,next;
int val,cost;
}node;
node E[maxn];
int head[maxm],dis[maxm],visit[maxm],pre[maxm],pos[maxm],cnt;
void init()
{
memset(head,-1,sizeof(head));
cnt=0;
}
void add(int from,int to,int val,int cost)
{
E[cnt].from=from,E[cnt].to=to,E[cnt].val=val,E[cnt].cost=cost;
E[cnt].next=head[from],head[from]=cnt++;
E[cnt].from=to,E[cnt].to=from,E[cnt].val=0,E[cnt].cost=-cost;
E[cnt].next=head[to],head[to]=cnt++;
}
bool spfa(int s,int t,int n)
{
int to,val,cost;
for(int i=0;i<=n;i++)
{
dis[i]=inf,visit[i]=0,pre[i]=-1;
}
dis[s]=0,visit[s]=1,pre[s]=s;
queue<int>Q;
Q.push(s);
while(!Q.empty())
{
int k=Q.front();
Q.pop();
visit[k]=0;
for(int i=head[k];i!=-1;i=E[i].next)
{
to=E[i].to;
val=E[i].val;
cost=E[i].cost;
if(val>0&&dis[k]+cost<dis[to])
{
dis[to]=dis[k]+cost;
pre[to]=k;
pos[to]=i;
if(visit[to])
continue;
visit[to]=1;
Q.push(to);
}
}
}
if(pre[t]!=-1&&dis[t]<inf)
return true;
return false;
}
int MaxCostFlow(int s,int t,int n)
{
int costflow=0,netflow=0,min;
while(spfa(s,t,n))
{
min=inf;
for(int i=t;i!=s;i=pre[i])
{
min=Min(min,E[pos[i]].val);
}
netflow+=min;
costflow+=min*dis[t];
for(int i=t;i!=s;i=pre[i])
{
E[pos[i]].val-=min;
E[pos[i]^1].val+=min;
}
}
return -costflow;
}
int main()
{
int s,t,n,x,sum;
while(~scanf("%d",&n))
{
init();
sum=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
scanf("%d",&x);
if((i==0&&j==0)||(i==n-1&&j==n-1))
{
add(i*n+j,i*n+j+n*n,2,-x);
sum+=x;
}
else
{
add(i*n+j,i*n+j+n*n,1,-x);
}
if(i+1<n)
{
add(i*n+j+n*n,(i+1)*n+j,1,0);
}
if(j+1<n)
{
add(i*n+j+n*n,i*n+j+1,1,0);
}
}
s=2*n*n+1,t=2*n*n+2;
add(s,0,2,0);
add(2*n*n-1,t,2,0);
printf("%d\n",MaxCostFlow(s,t,t+10)-sum);
}
return 0;
}
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
#define Min(a,b) a<b?a:b
#define maxn 40000+10
#define maxm 20000+10
#define inf 0xffffff
using namespace std;
typedef struct
{
int from,to,next;
int val,cost;
}node;
node E[maxn];
int head[maxm],dis[maxm],visit[maxm],pre[maxm],pos[maxm],cnt;
void init()
{
memset(head,-1,sizeof(head));
cnt=0;
}
void add(int from,int to,int val,int cost)
{
E[cnt].from=from,E[cnt].to=to,E[cnt].val=val,E[cnt].cost=cost;
E[cnt].next=head[from],head[from]=cnt++;
E[cnt].from=to,E[cnt].to=from,E[cnt].val=0,E[cnt].cost=-cost;
E[cnt].next=head[to],head[to]=cnt++;
}
bool spfa(int s,int t,int n)
{
int to,val,cost;
for(int i=0;i<=n;i++)
{
dis[i]=inf,visit[i]=0,pre[i]=-1;
}
dis[s]=0,visit[s]=1,pre[s]=s;
queue<int>Q;
Q.push(s);
while(!Q.empty())
{
int k=Q.front();
Q.pop();
visit[k]=0;
for(int i=head[k];i!=-1;i=E[i].next)
{
to=E[i].to;
val=E[i].val;
cost=E[i].cost;
if(val>0&&dis[k]+cost<dis[to])
{
dis[to]=dis[k]+cost;
pre[to]=k;
pos[to]=i;
if(visit[to])
continue;
visit[to]=1;
Q.push(to);
}
}
}
if(pre[t]!=-1&&dis[t]<inf)
return true;
return false;
}
int MaxCostFlow(int s,int t,int n)
{
int costflow=0,netflow=0,min;
while(spfa(s,t,n))
{
min=inf;
for(int i=t;i!=s;i=pre[i])
{
min=Min(min,E[pos[i]].val);
}
netflow+=min;
costflow+=min*dis[t];
for(int i=t;i!=s;i=pre[i])
{
E[pos[i]].val-=min;
E[pos[i]^1].val+=min;
}
}
return -costflow;
}
int main()
{
int s,t,n,x,sum;
while(~scanf("%d",&n))
{
init();
sum=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
scanf("%d",&x);
if((i==0&&j==0)||(i==n-1&&j==n-1))
{
add(i*n+j,i*n+j+n*n,2,-x);
sum+=x;
}
else
{
add(i*n+j,i*n+j+n*n,1,-x);
}
if(i+1<n)
{
add(i*n+j+n*n,(i+1)*n+j,1,0);
}
if(j+1<n)
{
add(i*n+j+n*n,i*n+j+1,1,0);
}
}
s=2*n*n+1,t=2*n*n+2;
add(s,0,2,0);
add(2*n*n-1,t,2,0);
printf("%d\n",MaxCostFlow(s,t,t+10)-sum);
}
return 0;
}
hdu 2686 Matrix【最大费用流】
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。