【题解】P1006 传纸条

题面

题目传送门

前言

基本上和 P1004 思路一致……

正文

直接贴个代码吧!

代码

DP:

#include<iostream>
#define int long long
using namespace std;
const int maxn=55;
int m,n,a[maxn][maxn],f[maxn][maxn][maxn][maxn];
signed main(){
    cin>>m>>n;
    for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
			cin>>a[i][j];
		}
	}
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
			for(int k=i+1;k<=m;k++){
				for(int l=1;l<=j-1;l++){
					f[i][j][k][l]=max(f[i][j-1][k][l-1],max(f[i][j-1][k-1][l],max(f[i-1][j][k-1][l],f[i-1][j][k][l-1])))+a[i][j]+a[k][l];
				}
			}
		}
	}
    cout<<f[m-1][n][m][n-1]<<endl;
    return 0;    
}

费用流:

#include<iostream>
#include<cstring>
#include<queue>
#define endl '\n'
#define int long long
using namespace std;
const int maxn=64,maxm=5e6+10,inf=9e18;
int n,m,a[maxn][maxn];
int head[maxm],tot=1;
struct node{
	int to,nxt,flow,val;
}e[maxm];
int S,T,pre[maxm],last[maxm],fl[maxm],dis[maxm];
bool vis[maxm];
queue<int> q;
inline int id(int x,int y){
	return (x-1)*m+y;
}
inline void add(int u,int v,int fl,int w){
	e[++tot].to=v;
	e[tot].flow=fl;
	e[tot].val=w;
	e[tot].nxt=head[u];
	head[u]=tot;
	return;
}
inline void build(){
	S=0;
	T=2*n*m+1;
	add(S,id(1,1)+n*m,2,0);
	add(id(1,1)+n*m,S,0,0);
	add(id(n,m),T,2,0);
	add(T,id(n,m),0,0);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(i+1<=n){
				add(id(i,j)+n*m,id(i+1,j),inf,0);
				add(id(i+1,j),id(i,j)+n*m,0,0);
			}
			if(j+1<=m){
				add(id(i,j)+n*m,id(i,j+1),inf,0);
				add(id(i,j+1),id(i,j)+n*m,0,0);
			}
			add(id(i,j),id(i,j)+n*m,1,-a[i][j]);
			add(id(i,j)+n*m,id(i,j),0,a[i][j]);
		}
	}
	return;
}
inline bool spfa(){
	memset(vis,false,sizeof(vis));
	memset(dis,0x7f,sizeof(dis));
	memset(fl,0x7f,sizeof(fl));
	q.push(S);
	dis[S]=0;
	vis[S]=true;
	pre[T]=-1;
	while(!q.empty()){
		int u=q.front();
		q.pop();
		vis[u]=false;
		for(int i=head[u];i;i=e[i].nxt){
			int v=e[i].to,f=e[i].flow,w=e[i].val;
			if(f&&dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				pre[v]=u;
				last[v]=i;
				fl[v]=min(fl[u],f);
				if(!vis[v]){
					vis[v]=true;
					q.push(v);
				}
			}
		}
	}
	return ~pre[T];
}
inline int mcmf(){
	int res=0;
	while(spfa()){
		res+=(fl[T]*dis[T]);
		for(int i=T;i!=S;i=pre[i]){
			e[last[i]].flow-=fl[T];
			e[last[i]^1].flow+=fl[T];
		}
	}
	return res;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
		}
	}
	build();
	int ans=mcmf();
	cout<<-ans<<endl;
	return 0;
}

后记

nyn 学姐好巨啊~

完结撒花!

posted @ 2024-12-19 18:19  sunxuhetai  阅读(18)  评论(0)    收藏  举报