狼抓兔子 BZOJ- 1001 最小割

https://www.lydsy.com/JudgeOnline/problem.php?id=1001

一个图,问你花费多少才能把到终点的所有边堵住...

就是求一个最小割,把$(1,1)$和$(n,m)$ 分开,按他所说的建图就行

不过点数和边数需要开到1e6和1e7...

速度..还能接受,不过这个题应该还能转化为反向图上的最短路解决吧?

(以下是AC代码,但是实际上我本机会RE,不知道为什么..)

#include <bits/stdc++.h>
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pp pair<int,int>
#define rep(ii,a,b) for(int ii=a;ii<=b;ii++)
#define	per(ii,a,b) for(int ii=a;ii>=b;ii--)
#define show(x) cout<<#x<<"="<<x<<endl
#define show2(x,y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl
#define show3(x,y,z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define showa(a,b) cout<<#a<<'['<<b<<"]="<<b[a]<<endl
using namespace std;
const int maxn=1e6+10;
const int maxm=1e7+10;
const int INF=0x3f3f3f3f;
int casn,n,m,k;
struct node {int to;int cap;int next;}e[maxm];
int ss,tt,head[maxn],nume,dis[maxn];
inline void addx(int a,int b,int c){
	e[++nume]=(node){b,c,head[a]};
	head[a]=nume;
}
inline void add(int a,int b,int c){
	addx(a,b,c);addx(b,a,c);
}
bool bfs(int s=ss,int t=tt){
	int top=0,end=1;
	int q[maxn];
	q[0]=s;
//	for(int i=0;i<=t;i++) dis[i]=0;
	memset(dis,0,sizeof dis);
	dis[s]=1;
	while(top!=end){
		int now=q[top++];top%=maxn;
		for(int i=head[now];i;i=e[i].next){
			int to=e[i].to;
			if(!dis[to]&&e[i].cap){
				dis[to]=dis[now]+1;
				if(to==t)break;
				q[end++]=to;end%=maxn;
			}
		}
	}
	return dis[t];
}
int dfs(int now=ss,int last=INF){
	if(now==tt)return last;
	int flow=0,det;
	for(int i=head[now];i;i=e[i].next){
		int to=e[i].to;
		if(e[i].cap&&dis[to]==dis[now]+1){
			det=dfs(to,min(last-flow,e[i].cap));
			flow+=det;
			e[i].cap-=det;
			e[i^1].cap+=det;
			if(flow==last) return last;
		}
	}
	dis[now]=-1;
	return flow;
}
inline int read(){
	int num=0,flag=1,ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){num=(num<<3)+(num<<1)+ch-'0',ch=getchar();}
	return flag*num;
}

int a,b,c;
int main(){
//#define test
#ifdef test
	freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#endif
	nume=1;
	n=read();m=read();
	rep(i,1,n){
		rep(j,2,m){
			a=read();
			add(m*(i-1)+j,m*(i-1)+j-1,a);
		}
	}
	rep(i,2,n){
		rep(j,1,m){
			a=read();
			add(m*(i-1)+j,m*(i-2)+j,a);
		}
	}
	rep(i,2,n){
		rep(j,2,m){
			a=read();
			add(m*(i-1)+j,m*(i-2)+j-1,a);
		}
	}
	ss=1,tt=n*m;
	int ans=0;
	while(bfs()) ans+=dfs();
	printf("%d\n",ans);


#ifdef test
	fclose(stdin);fclose(stdout);system("out.txt");
#endif
	return 0;
}

  

posted @ 2018-05-23 21:51  nervending  阅读(172)  评论(0编辑  收藏  举报