版权声明:~~~感谢支持! https://blog.csdn.net/qq_39897867/article/details/89000089
题目
http://poj.org/problem?id=3422
解题思路
先拆点,然后两边,最后跑费用流的模板。
最长路。
bool spfa(){
queue<int> q;
memset(d,0xcf,sizeof(d));
memset(v,0,sizeof(v));
q.push(s); d[s]=0; v[s]=1;
incf[s]=1<<30;
while(q.size()){
int x=q.front(); v[x]=0; q.pop();
for (int i=head[x];i;i=a[i].next){
if (a[i].z==0) continue;
int y=a[i].y;
if (d[y]<d[x]+a[i].c) {
d[y]=d[x]+a[i].c;
incf[y]=min(incf[x],a[i].z);
pre[y]=i;
if (!v[y]) v[y]=1,q.push(y);
}
}
}
return (d[t]==0xcfcfcfcf)?0:1;
}
void update(){
int x=t;
while (x!=s) {
int i=pre[x];
a[i].z-=incf[t]; a[i^1].z+=incf[t]; x=a[i^1].y;
}
maxflow+=incf[t],ans+=d[t]*incf[t];
}
代码
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define rep(i,x,y) for (register int i=x;i<=y;i++)
using namespace std;
const int N=5010,M=200010;
struct node{int y,z,c,next;}a[M];
int d[N],incf[N],pre[N],v[N],head[N];
int n,k,tot=1,s,t,maxflow,ans;
void add(int x,int y,int z,int c){
a[++tot]=(node){y,z,c,head[x]}; head[x]=tot;
a[++tot]=(node){x,0,-c,head[y]}; head[y]=tot;
}
int num(int i,int j,int k){return (i-1)*n+j+k*n*n;}
bool spfa(){
queue<int> q;
memset(d,0xcf,sizeof(d));
memset(v,0,sizeof(v));
q.push(s); d[s]=0; v[s]=1;
incf[s]=1<<30;
while(q.size()){
int x=q.front(); v[x]=0; q.pop();
for (int i=head[x];i;i=a[i].next){
if (a[i].z==0) continue;
int y=a[i].y;
if (d[y]<d[x]+a[i].c) {
d[y]=d[x]+a[i].c;
incf[y]=min(incf[x],a[i].z);
pre[y]=i;
if (!v[y]) v[y]=1,q.push(y);
}
}
}
return (d[t]==0xcfcfcfcf)?0:1;
}
void update(){
int x=t;
while (x!=s) {
int i=pre[x];
a[i].z-=incf[t]; a[i^1].z+=incf[t]; x=a[i^1].y;
}
maxflow+=incf[t],ans+=d[t]*incf[t];
}
int main(){
scanf("%d%d",&n,&k);
s=1,t=2*n*n;
rep(i,1,n) rep(j,1,n){
int c; scanf("%d",&c);
add(num(i,j,0),num(i,j,1),1,c);
add(num(i,j,0),num(i,j,1),k-1,0);
if (j<n) add(num(i,j,1),num(i,j+1,0),k,0);
if (i<n) add(num(i,j,1),num(i+1,j,0),k,0);
}
while (spfa()) update(); printf("%d",ans);
}