1. 程式人生 > >洛谷P4001 [BJOI2006]狼抓兔子(平面圖轉對偶圖)

洛谷P4001 [BJOI2006]狼抓兔子(平面圖轉對偶圖)

bool .html next fine pri n) www moto tdi

傳送門

明明只要最小割加點優化就能過的東西……

然而我偏偏要去學平面圖轉對偶圖結果發現課件關鍵地方看不清->這裏

而且建圖累的半死……

說實話只要最大流建圖的時候反向邊直接設為當前邊容量再加個當前弧優化就好了……

至於平面圖轉對偶圖……自己看代碼我無能為力了……

 1 //minamoto
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<queue>
 5
#include<cstring> 6 using namespace std; 7 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 8 char buf[1<<21],*p1=buf,*p2=buf; 9 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;} 10 template<class
T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;} 11 inline int read(){ 12 #define num ch-‘0‘ 13 char ch;bool flag=0;int res; 14 while(!isdigit(ch=getc())) 15 (ch==-)&&(flag=true); 16 for(res=num;isdigit(ch=getc());res=res*10+num); 17 (flag)&&(res=-res);
18 #undef num 19 return res; 20 } 21 const int N=3000005; 22 int ver[N<<1],Next[N<<1],head[N],edge[N<<1],tot; 23 inline void add(int u,int v,int e){ 24 ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e; 25 ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=e; 26 } 27 bool vis[N];int s,t,dis[N];queue<int> q; 28 int spfa(){ 29 memset(dis,0x3f,sizeof(dis)); 30 vis[s]=1,q.push(s),dis[s]=0; 31 while(!q.empty()){ 32 int u=q.front();q.pop();vis[u]=0; 33 for(int i=head[u];i;i=Next[i]){ 34 int v=ver[i]; 35 if(dis[v]>dis[u]+edge[i]){ 36 dis[v]=dis[u]+edge[i]; 37 if(!vis[v]) q.push(v),vis[v]=1; 38 } 39 } 40 } 41 return dis[t]; 42 } 43 int n,m; 44 inline void heng(int i,int j,int k){ 45 if(i==1) add(s,j,k); 46 else if(i==n) add((2*(n-1)-1)*(m-1)+j,t,k); 47 else add((2*(i-1)-1)*(m-1)+j,2*(i-1)*(m-1)+j,k); 48 } 49 inline void shu(int i,int j,int k){ 50 if(j==1) add((i*2-1)*(m-1)+1,t,k); 51 else if(j==m) add(s,2*i*(m-1)-(m-1),k); 52 else add((i-1)*2*(m-1)+j-1,((i-1)*2+1)*(m-1)+j,k); 53 } 54 inline void xie(int i,int j,int k){ 55 add((i-1)*2*(m-1)+j,(i-1)*2*(m-1)+m-1+j,k); 56 } 57 int main(){ 58 //freopen("testdata.in","r",stdin); 59 n=read(),m=read(); 60 s=(n-1)*(m-1)*2+1,t=(n-1)*(m-1)*2+2; 61 for(int i=1;i<=n;++i) 62 for(int j=1;j<m;++j){ 63 int x=read();heng(i,j,x); 64 } 65 for(int i=1;i<n;++i) 66 for(int j=1;j<=m;++j){ 67 int x=read();shu(i,j,x); 68 } 69 for(int i=1;i<n;++i) 70 for(int j=1;j<m;++j){ 71 int x=read();xie(i,j,x); 72 } 73 printf("%d\n",spfa()); 74 return 0; 75 }

洛谷P4001 [BJOI2006]狼抓兔子(平面圖轉對偶圖)