1. 程式人生 > >刷題計劃

刷題計劃

brush -s logs class back != san fine main

開個坑不然刷題沒動力QAQ

幹脆叫做刷題計劃。。。

既然開了坑就要填滿QWQ,加油!

正好實力弱多刷題也挺好的QAQ

1/50

Bzoj-1001 狼抓兔子

題意:求最小割

分析:因為最小割=最大流,直接跑一遍dinic求最大流就好了。最大流參照的是黃學長的模板

代碼:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<vector>
#include<map>
#include<queue> 
#include<algorithm>
using namespace std;
#define maxn 1000005
#define ll long long
int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
int n,m;
int h[maxn],q[maxn];
struct pos{
	int to,from,v,nxt;
}e[maxn*6];
int head[maxn],edge;
void add(int x,int y,int z){
	e[++edge].to=y;e[edge].from=x;e[edge].v=z;
	e[edge].nxt=head[x];head[x]=edge;
}
bool bfs(){
	int now;memset(h,-1,sizeof(h));
	int hd=0,tl=1;
	q[hd]=1;h[1]=0;
	while(hd!=tl){
		now=q[hd++];
		for(int i=head[now];i;i=e[i].nxt){
			if(e[i].v&&h[e[i].to]==-1){
				h[e[i].to]=h[now]+1;
				q[tl++]=e[i].to;
			}
		}
	}
	return h[n*m]!=-1;
}
int dfs(int x,int mn){
	if(x==n*m) return mn;
	int w,used=0;
	for(int i=head[x];i;i=e[i].nxt)
		if(e[i].v&&h[e[i].to]==h[x]+1){
			w=mn-used;w=dfs(e[i].to,min(w,e[i].v));
			e[i].v-=w;
			e[i+1].v+=w;
			used+=w;
			if(used==mn) return mn;
		}
	if(!used) h[x]=-1;
	return used;
}
int ans;
int dinic(){while(bfs())ans+=dfs(1,0x7fffffff);}
int main(){
	n=read();m=read();
	for(int i=1;i<=n;i++)
		for(int j=1;j<m;j++){
			int x=read();
			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;i++)
		for(int j=1;j<=m;j++){
			int x=read();
			add((i-1)*m+j,i*m+j,x);
			add(i*m+j,(i-1)*m+j,x);
		}
	for(int i=1;i<n;i++)
		for(int j=1;j<m;j++){
			int x=read();
			add((i-1)*m+j,i*m+j+1,x);
			add(i*m+j+1,(i-1)*m+j,x);
		}
	dinic();printf("%d\n",ans);
}

未完待續

刷題計劃