bzoj 1001 狼抓兔子

2022-06-04 16:15:09 字數 2017 閱讀 8485

題解:其實剛布置這道題的時候,我是拒絕的,後來聽大犇們的的話,潛下心來學了一點(又經過數小時的除錯之後)才寫出了正解

正解的概念表達是:利用平面圖的性質,把最大流問題轉化成最小割問題,再用最短路來解決(其實我也不懂這tm都是什麼鬼)

先介紹一下對偶圖吧:

對於每乙個平面圖g,都有乙個對偶圖g'與之對應,其構造方法如下:

圖g乙個面為圖g'中的乙個點,圖g中一條邊的割線為圖g'這條邊兩邊兩個面(所對應的點)之間的連線,邊權也相等

如果一條邊只處於乙個麵內,就構造那個面自己連向自己的邊(這條性質在這道題中並沒有用到)

對偶圖構造樣例(來自@reddest):

平面圖g:

對偶圖g':

得到平面圖與對偶圖之間的關係:對偶圖的點數等於平面圖的面數,對偶圖的邊數等於平面圖的邊數

(更多證明以及性質定理之類的參見:

那麼,對於這道題來說還要再加幾步:在構造對偶圖之前在起點和終點之間連一條邊,把最外層的面分成兩半,乙個作為起點,乙個作為終點;

構造過程中,不要構造起點和終點之間的邊(其實虛擬出來的邊沒有邊權,也沒法構造)

構造樣例的對偶圖:

接著用各種演算法求最短路即可

我用的spfa:

#include#define maxn 2000000

#define inf 214748364

intn,m,nn,heads[maxn],d[maxn],q[maxn],head,tail,cnt;

bool

viss[maxn];

struct

edge

e[maxn*3

];inline

int min(int x,int

y)void add(int x,int y,intz);

heads[x]=cnt;

}void inedge()//

建對偶圖

cnt=(m-1)*2

;

for(int i=2;i)

cnt+=(m-1

); }

for(int i=1;i<=m-1;i++)

//豎邊

cnt=m;

for(int i=1;i<=n-1;i++)

scanf("%d

",&x);

add(

0,cnt-m+1,x);add(cnt-m+1,0

,x);

cnt+=m;

}//斜邊

cnt=0

;

for(int i=1;i<=n-1;i++)

cnt+=(m-1

); }

}void

spfa()}}

viss[q[head++]]=false

; }

}int

main()

printf(

"%d\n

",ans==inf?0

:ans);

return0;

}else

if(m==1

)

printf(

"%d\n

",ans==inf?0

:ans);

return0;

}nn=(n-1)*(m-1)*2+1

; inedge();

for(int i=1;i<=nn;i++)d[i]=inf;

spfa();

printf(

"%d\n

",d[nn]);

return0;

}

BZoj1001狼抓兔子

description 現在小朋友們最喜歡的 喜羊羊與灰太狼 話說灰太狼抓羊不到,但抓兔子還是比較在行的,而且現在的兔子還比較笨,它們只有兩個窩,現在你做為狼王,面對下面這樣乙個網格的地形 左上角點為 1,1 右下角點為 n,m 上圖中n 4,m 5 有以下三種型別的道路 1 x,y x 1,y 2...

bzoj1001 狼抓兔子

time limit 15 sec memory limit 162 mb submit 12719 solved 3017 submit status discuss description 現在小朋友們最喜歡的 喜羊羊與灰太狼 話說灰太狼抓羊不到,但抓兔子還是比較在行的,而且現在的兔子還比較笨,...

BZOJ 1001 狼抓兔子

參考 本題的題解 還有那篇平面圖網路流的 兩極相通 最大 最小定理在資訊學競賽中的應用 兩篇足夠了。pragma comment include include include include using namespace std define mp i,j make pair i,j defin...