题目传送门:BZOJ1001
%%%LYF大神,打的是SPFA,如果不用vector和queue,肯定比我跑的快……
说实话,如果这题的数据造的强大一些,我的dinic应该是要被卡掉的。
这题我打的是网络最大流,也是我看了题目后想到的第一种解法。
主要是建图,要好好想想,怎样把二维的图转换成一维的n*m个点。
附上AC代码:
#include <cstdio>
#include <cstring>
using namespace std;
struct note{
int from,to,w,nt;
}side[6*1010*1010];
int n,m,x,h[1010*1010],ans,c[1010*1010],num,tou,wei,que[1010*1010];
void add(int a,int b,int w){
side[num]=(note){a,b,w,h[a]};
h[a]=num++;
}
int bfs(){
memset(c,0,sizeof c);
que[tou=wei=1]=1;c[1]=1;
while (tou<=wei){
int p=que[tou++];
for (int i=h[p]; ~i; i=side[i].nt)
if (!c[side[i].to]&&side[i].w){
c[side[i].to]=c[p]+1;
que[++wei]=side[i].to;
}
if (c[n*m]) break;
}
return c[n*m];
}
int min(int a,int b){
return a<b?a:b;
}
int so(int x,int ans){
if (x==n*m) return ans;
int a,f=0;
for (int i=h[x]; ~i; i=side[i].nt)
if (c[side[i].to]==c[x]+1&&side[i].w&&(a=so(side[i].to,min(side[i].w,ans)))){
side[i].w-=a;
side[i^1].w+=a;
f+=a;ans-=a;
if (ans==0) break;
}
if (!f) c[x]=0;
return f;
}
void read(int& a){
static char c=getchar();a=0;
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') a=a*10+c-'0',c=getchar();
}
int main(void){
read(n),read(m);
memset(h,-1,sizeof h);
for (int i=1; i<=n; ++i)
for (int j=1; j<=m-1; ++j){
read(x);
add((i-1)*m+j,(i-1)*m+j+1,x);
add((i-1)*m+j+1,(i-1)*m+j,x);
}
for (int i=1; i<=n-1; ++i)
for (int j=1; j<=m; ++j){
read(x);
add((i-1)*m+j,i*m+j,x);
add(i*m+j,(i-1)*m+j,x);
}
for (int i=1; i<=n-1; ++i)
for (int j=1; j<=m-1; ++j){
read(x);
add((i-1)*m+j,i*m+j+1,x);
add(i*m+j+1,(i-1)*m+j,x);
}
while (bfs()) ans+=so(1,0x7fffffff);
printf("%d",ans);
return 0;
}
说实话,如果这题的数据造的强大一些,我的dinic应该是要被卡掉的。