洛谷P4001 [BJOI2006]狼抓兔子(平面图转对偶图)

传送门

 

明明只要最小割加点优化就能过的东西……

然而我偏偏要去学平面图转对偶图结果发现课件关键地方看不清->这里

而且建图累的半死……

说实话只要最大流建图的时候反向边直接设为当前边容量再加个当前弧优化就好了……

至于平面图转对偶图……自己看代码我无能为力了……

 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 }

 

posted @ 2018-08-31 13:18  bztMinamoto  阅读(158)  评论(0编辑  收藏  举报
Live2D