1. 程式人生 > >bzoj1001狼抓兔子

bzoj1001狼抓兔子

n) std 灰太狼 top bool 表示 continue 能夠 long

1001: [BeiJing2006]狼抓兔子

現在小朋友們最喜歡的"喜羊羊與灰太狼",話說灰太狼抓羊不到,但抓兔子還是比較在行的,
而且現在的兔子還比較笨,它們只有兩個窩,現在你做為狼王,面對下面這樣一個網格的地形:
左上角點為(1,1),右下角點為(N,M)(上圖中N=4,M=5).有以下三種類型的道路
1:(x,y)< == >(x+1,y)
2:(x,y)< == >(x,y+1)
3:(x,y)< == >(x+1,y+1)
道路上的權值表示這條路上最多能夠通過的兔子數,道路是無向的. 左上角和右下角為兔子的兩個窩,
開始時所有的兔子都聚集在左上角(1,1)的窩裏,現在它們要跑到右下解(N,M)的窩中去,狼王開始伏擊
這些兔子.當然為了保險起見,如果一條道路上最多通過的兔子數為K,狼王需要安排同樣數量的K只狼,
才能完全封鎖這條道路,你需要幫助狼王安排一個伏擊方案,使得在將兔子一網打盡的前提下,參與的
狼的數量要最小。因為狼還要去找喜羊羊麻煩.

對偶圖的第一題。

平面圖的對偶圖是把平面圖的面變成點,外面的部分變為一個點。

如果要求一個平面圖的最大流,我們可以把它轉化為它對偶圖的最短路。

#include<bits/stdc++.h>
using namespace std;
#define REP(i,st,ed) for(register int i=st,i##end=ed;i<=i##end;++i)
#define DREP(i,st,ed) for(register int i=st,i##end=ed;i>=i##end;--i)
#define id(x,y) ((x-1)*m+y)
typedef
long long ll; inline int read(){ int x; char c; int f=1; while((c=getchar())!=‘-‘ && (c<‘0‘ || c>‘9‘)); if(c==‘-‘) c=getchar(),f=-1; x=c^‘0‘; while((c=getchar())>=‘0‘ && c<=‘9‘) x=(x<<1)+(x<<3)+(c^‘0‘); return x*f; } inline ll readll(){ ll x; char
c; ll f=1; while((c=getchar())!=‘-‘ && (c<‘0‘ || c>‘9‘)); if(c==‘-‘) c=getchar(),f=-1; x=c^‘0‘; while((c=getchar())>=‘0‘ && c<=‘9‘) x=(x<<1ll)+(x<<3ll)+(c^‘0‘); return x*f; } const int maxn=2000000+10,inf=0x3f3f3f3f; int Begin[maxn],Next[maxn*3],to[maxn*3],w[maxn*3],e; inline bool chkmin(int &x,int y){return (y<x)?(x=y,1):0;} void add_edge(int x,int y,int z){ to[++e]=y; Next[e]=Begin[x]; Begin[x]=e; w[e]=z; } void add(int x,int y){ int z=read(); add_edge(x,y,z),add_edge(y,x,z); } struct point{ int x,y; bool operator <(const point &rhs) const{ return y>rhs.y; } }; priority_queue<point> q; bool vis[maxn]; int d[maxn]; int S,T; int main(){ #ifndef ONLINE_JUDGE freopen("dot.in","r",stdin); freopen("dot.out","w",stdout); #endif int n=read(),m=read(); if(n==1 || m==1){ if(n>m) swap(n,m); int ans=inf; REP(i,1,m-1){ int x=read(); chkmin(ans,x); } if(ans==inf) printf("0\n"); else printf("%d\n",ans); return 0; } n--,m--; S=n*m*2+1,T=n*m*2+2; REP(i,1,m) add(S,id(1,i)*2-1); REP(i,2,n) REP(j,1,m) add(id(i-1,j)*2,id(i,j)*2-1); REP(i,1,m) add(id(n,i)*2,T); REP(i,1,n) REP(j,1,m+1){ if(j==1) add(id(i,j)*2,T); else if(j==jend) add(S,id(i,j-1)*2-1); else add(id(i,j)*2,id(i,j-1)*2-1); } REP(i,1,n) REP(j,1,m) add(id(i,j)*2-1,id(i,j)*2); memset(d,inf,sizeof(d)); q.push((point){S,0});d[S]=0; while(!q.empty()){ point u=q.top();q.pop(); if(vis[u.x]) continue; vis[u.x]=1; if(u.x==T){ printf("%d\n",u.y); return 0; } for(int i=Begin[u.x];i;i=Next[i]) if(chkmin(d[to[i]],u.y+w[i]) && !vis[to[i]]) q.push((point){to[i],d[to[i]]}); } return 0; } ?

bzoj1001狼抓兔子