BZOJ [BeiJing2006]狼抓兔子 平面图最大流
题意:
中文题。
思路:
裸的最大流,然而点数太多,所以,转换成平面图最大流——最短路
裸的不能再裸的平面图最大流
竟然没有spfa快,抑郁。。
刷了几天TYVJ,发现变弱了。。其实本来就特别弱
(边需要建成双向的,我就不改了)
View Code
1 #include <cstring> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <algorithm> 5 #include <iostream> 6 7 #define N 3000000 8 #define M 10000000 9 10 using namespace std; 11 12 struct HP 13 { 14 int x,d; 15 }hp[N],sta; 16 17 int head[N],next[M],to[M],len[M],dis[N],cnt,n,m,size,S,T; 18 19 inline bool cmp(const HP&a,const HP &b) 20 { 21 return a.d>b.d; 22 } 23 24 inline void add(int u,int v,int w) 25 { 26 to[cnt]=v; len[cnt]=w; next[cnt]=head[u]; head[u]=cnt++; 27 //printf("%d %d %d\n",u,v,w); 28 } 29 30 inline int getnum(int x,int y,int pd) 31 { 32 int rt=(x-1)*(m-1)+y; 33 if(pd==1) return rt; 34 return rt+(n-1)*(m-1); 35 } 36 37 void read() 38 { 39 memset(head,-1,sizeof head); cnt=0; 40 S=(n-1)*(m-1)*2+1; T=S+1; 41 //printf("%d----%d\n",S,T); 42 int a; 43 for(int i=1;i<=n;i++) 44 for(int j=1;j<m;j++) 45 { 46 scanf("%d",&a); 47 if(i==1) add(S,getnum(i,j,2),a); 48 else if(i==n) add(getnum(i-1,j,1),T,a); 49 else add(getnum(i-1,j,1),getnum(i,j,2),a); 50 } 51 for(int i=1;i<n;i++) 52 for(int j=1;j<=m;j++) 53 { 54 scanf("%d",&a); 55 if(j==1) add(getnum(i,j,1),T,a); 56 else if(j==m) add(S,getnum(i,j-1,2),a); 57 else add(getnum(i,j,1),getnum(i,j-1,2),a); 58 } 59 for(int i=1;i<n;i++) 60 for(int j=1;j<m;j++) 61 { 62 scanf("%d",&a); 63 add(getnum(i,j,2),getnum(i,j,1),a); 64 } 65 } 66 67 void dijkstra() 68 { 69 memset(dis,0x3f,sizeof dis); 70 size=1; 71 hp[1].x=S; hp[1].d=0; dis[S]=0; 72 while(size) 73 { 74 sta=hp[1]; 75 pop_heap(hp+1,hp+1+size,cmp); size--; 76 if(sta.d>dis[sta.x]) continue; 77 for(int i=head[sta.x];~i;i=next[i]) 78 if(dis[to[i]]>dis[sta.x]+len[i]) 79 { 80 dis[to[i]]=dis[sta.x]+len[i]; 81 size++; 82 hp[size].x=to[i]; hp[size].d=dis[to[i]]; 83 push_heap(hp+1,hp+1+size,cmp); 84 } 85 } 86 printf("%d\n",dis[T]); 87 } 88 89 int main() 90 { 91 while(scanf("%d%d",&n,&m)!=EOF) 92 { 93 read(); 94 dijkstra(); 95 } 96 return 0; 97 }
没有人能阻止我前进的步伐,除了我自己!