1. 程式人生 > 實用技巧 >#1001. [BeiJing2006]狼抓兔子

#1001. [BeiJing2006]狼抓兔子

這道題要求的是最小割,但是用網路流的話明顯太大了,看了網上的資料,才發現對於平面圖(!!!),可以將網路流轉化成最短路的方式,在網路流中,我們將一個點看成節點,將邊權當作最大容量,而轉化為最短路後,我們將區域看成一個節點,將兩個區域之間的邊權看成費用,求最短路就相當於求最小割了。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define LL long long
#define ull unsigned long long
#define PI acos(-1.0)
#define eps 1e-12
#define
fi first #define se second #define MEM(a,b) memset((a),(b),sizeof(a)) #define mod(x) ((x)%MOD) #define wz cout<<"-----"<<endl; #define pb push_back #define mp make_pair #define pll pair <LL, LL> #define pii pair <int, int> #define rep(i,x) for(int i=1;i<=x;i++) const int INF_INT = 2147483647
; const ll INF_LL = 9223372036854775807LL; const ull INF_ULL = 18446744073709551615Ull; const ll P = 92540646808111039LL; const ll maxn = 1e5 + 10, MOD = 1e9 + 7; const int Move[4][2] = {-1,0,1,0,0,1,0,-1}; const int Move_[8][2] = {-1,-1,-1,0,-1,1,0,-1,0,1,1,-1,1,0,1,1}; inline 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; const int N=3e6; const int M=7e6+10; struct edge{ ll to,ne,w; }e[M]; int head[N],cnt; void add(int x,int y,ll w){ e[cnt].to=y,e[cnt].ne=head[x],e[cnt].w=w,head[x]=cnt++; } ll dis[N];bool vis[N]; struct node{ ll dis,pos; bool operator <(const node &x)const{ return x.dis<dis; } }; priority_queue<node> st; ll dij(int S,int T){ memset(dis,0x3f,sizeof dis); dis[S]=0; st.push({0,S}); while(!st.empty()){ node tep=st.top();st.pop(); int x=tep.pos; if(vis[x])continue; vis[x]=1; for(int i=head[x];~i;i=e[i].ne){ int y=e[i].to; if(dis[y]>dis[x]+e[i].w){ dis[y]=dis[x]+e[i].w; if(!vis[y])st.push({dis[y],y}); } } } return dis[T]; } int main(){ memset(head,-1,sizeof head); int S,T;S=1,T=2234560; n=read(),m=read(); for(int i=1;i<=n;i++){ for(int j=1;j<m;j++){ int w=read(); int f,t; if(i==n)f=S; else f=(i-1)*(m-1)+j<<1; if(i==1)t=T; else t=(i-2)*(m-1)+j<<1|1; add(f,t,w); add(t,f,w); } } for(int i=1;i<n;i++){ for(int j=1;j<=m;j++){ int w=read(); int f,t; if(j==1)f=S; else f=(i-1)*(m-1)+j-1<<1; if(j==m)t=T; else t=(i-1)*(m-1)+j<<1|1; add(f,t,w); add(t,f,w); } } for(int i=1;i<n;i++){ for(int j=1;j<m;j++){ int w=read(); int f,t; f=(i-1)*(m-1)+j<<1|1; t=(i-1)*(m-1)+j<<1; add(f,t,w); add(t,f,w); } } cout<<dij(S,T)<<endl; return 0; }
View Code