HDU - 2686 Matrix

Matrix

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

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
ZJFC 2009-3 Programming Contest


比较简单的一道费用流,挺像网络流24题当中的一道题。


考虑建图:

  • 我们把每个点拆开,限流,费用为点的价值,流量为1
  • 建立S连向第一个点,最后一个点连向T
  • 最后补充第一个点入点与出点的一条边,流量为1,费用为0,因为起始点可以用两次,但价值使用一次。

AC代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int inf=0x3f3f3f3f;
const int N=1e4+10,M=1e5+10;
int n,v[N],e[N],g[N][N],s,t,base,d[N];
int head[N],nex[M],to[M],w[M],flow[M],tot=1;
inline void ade(int a,int b,int c,int d){
	to[++tot]=b; w[tot]=d; flow[tot]=c; nex[tot]=head[a]; head[a]=tot;
}
inline void add(int a,int b,int c,int d){
	ade(a,b,c,d);	ade(b,a,0,-d);
}
inline int id(int x,int y){
	return (x-1)*n+y;
}
inline bool spfa(){
	int vis[N]={0};	vis[s]=1;	queue<int> q;	q.push(s);
	memset(d,inf,sizeof d);	d[s]=0;
	while(q.size()){
		int u=q.front();	q.pop();	vis[u]=0;
		for(int i=head[u];i;i=nex[i]){
			if(flow[i]&&d[to[i]]>d[u]+w[i]){
				d[to[i]]=d[u]+w[i];
				v[to[i]]=u;	e[to[i]]=i;
				if(!vis[to[i]])	q.push(to[i]),vis[to[i]]=1;
			}
		}
	}
	return d[t]!=inf;
}
inline int EK(){
	int res=0;
	while(spfa()){
		int mi=inf;
		for(int i=t;i!=s;i=v[i])	mi=min(mi,flow[e[i]]);
		for(int i=t;i!=s;i=v[i])	flow[e[i]]-=mi,flow[e[i]^1]+=mi;
		res+=d[t]*mi;
	}
	return -res;
}
signed main(){
	while(~scanf("%d",&n)){
		tot=1;	memset(head,0,sizeof head);	s=0; t=n*n*2+1; base=n*n;
		for(int i=1;i<=n;i++)	for(int j=1;j<=n;j++)	scanf("%d",&g[i][j]);
		add(s,1,2,0);	add(id(n,n)+base,t,2,0);
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				add(id(i,j),id(i,j)+base,1,-g[i][j]);
				if(i<n)	add(id(i,j)+base,id(i+1,j),1,0);
				if(j<n) add(id(i,j)+base,id(i,j+1),1,0);
			}
		}
		add(1,1+base,1,0);	add(id(n,n),id(n,n)+base,1,0);
		printf("%d\n",EK());
	}
	return 0;
}
全部评论

相关推荐

在读外卷大学生:神仙排版,看的我头晕直接扔了
点赞 评论 收藏
分享
友友们,中小厂,设计模式,一般咋问呀,会问的很深吗
June丶:1. 按照设计模式分类回答:创建(工厂,单例),结构(组合,代理,外观),行为(策略,模版方法)。 2. 常见的应用:工厂+单例+策略(解耦,提高灵活性,扩展性),组合(解耦合,灵活,,提高代码复用),外观(提高安全性),模版(提高代码复用,灵活性) 3. 在回答出来这些常见实用场景+使用的优点基本就是满意回答了 4. 如果要是优质回答:可以提出你看过的源码中例如springboot中一些设计模式(不常用的代理,责任链,发布订阅),但是展现了你的钻研与热爱
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务