【题解】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 学姐好巨啊~
完结撒花!