NOI2009 植物大戰殭屍

2022-05-08 04:27:09 字數 4134 閱讀 1083

plants vs. zombies(pvz)是最近十分風靡的一款小遊戲。plants(植物)和zombies(殭屍)是遊戲的主角,其中plants防守,而 zombies進攻。該款遊戲包含多種不同的挑戰系列,比如protect your brain、bowling等等。其中最為經典的,莫過於玩家通過控制plants來防守zombies的進攻,或者相反地由玩家通過控制zombies 對plants發起進攻。

現在,我們將要考慮的問題是遊戲中zombies對plants的進攻,請注意,本題中規則與實際遊戲有所不同。遊戲中有兩種角色,plants和

zombies,每個plant有乙個攻擊位置集合,它可以對這些位置進行保護;而zombie進攻植物的方式是走到植物所在的位置上並將其吃掉。

遊戲的地圖可以抽象為乙個n行m列的矩陣,行從上到下用0到n–1編號,列從左到右用0到m–1編號;在地圖的每個位置上都放有乙個plant,為簡單起

見,我們把位於第r行第c列的植物記為pr,c。

plants分很多種,有攻擊類、防守類和經濟類等等。為了簡單的描述每個plant,定義score和attack如下:

score[pr,c]:zombie擊潰植物pr,c可獲得的能源。若score[pr,c]為非負整數,則表示擊潰植物pr,c可獲得能源score[pr,c],若為負數表示擊潰pr,c需要付出能源-score[pr,c]。

attack[pr,c]:植物pr,c能夠對zombie進行攻擊的位置集合。

zombies必須從地圖的右側進入,且只能沿著水平方向進行移動。zombies攻擊植物的唯一方式就是走到該植物所在的位置並將植物吃掉。因此zombies的進攻總是從地圖的右側開始。也就是說,對於第r行的進攻,zombies必須首先攻擊pr,m-1;

若需要對pr,c(0≤c<m-1)攻擊,必須將pr,m-1,pr,m-2…pr,c+1先擊潰,並移動到位置(r,c)才可進行攻擊。

在本題的設定中,plants的攻擊力是無窮大的,一旦zombie進入某個plant的攻擊位置,該zombie會被瞬間消滅,而該zombie沒有時

間進行任何攻擊操作。因此,即便zombie進入了乙個plant所在的位置,但該位置屬於其他植物的攻擊位置集合,則zombie會被瞬間消滅而所在位

置的植物則安然無恙(在我們的設定中,plant的攻擊位置不包含自身所在位置,否則你就不可能擊潰它了)。

zombies的目標是對plants的陣地發起進攻並獲得最大的能源收入。每一次,你可以選擇乙個可進攻的植物進行攻擊。本題的目標為,制定一套zombies的進攻方案,選擇進攻哪些植物以及進攻的順序,從而獲得最大的能源收入。

第一行包含兩個整數n,m,分別表示地圖的行數和列數。

接下來n×m行描述每個位置上植物的資訊。第r×m+c+

1行按照如下格式給出植物pr,c的資訊:第乙個整數為score[pr,c],第二個整數為集合attack[pr,c]中的位置個數w,接下來w個位

置資訊(r』,c』),表示pr,c可以攻擊位置第r』行第c』列。

包含乙個整數,表示可以獲得的最大能源收入。注意,你也可以選擇不進行任何攻擊,這樣能源收入為0。

3 2

10 0

20 0

-10 0

-5 1 0 0

100 1 2 1

100 0

樣例說明:

在樣例中,植物p1,1可以攻擊位置(0,0),p2, 0可以攻擊位置(2,1)。

乙個方案為,首先進攻p1,1,p0,1,此時可以攻擊p0,0。共得到能源收益為(-5)+20+10 = 25。注意,位置(2,1)被植物p2,0保護,所以無法攻擊第2行中的任何植物。

資料規模:

約20%的資料滿足1 ≤n,m≤ 5;

約40%的資料滿足1 ≤n,m≤ 10;

約100%的資料滿足1 ≤n≤ 20,1 ≤m≤ 30,-10000 ≤score≤ 10000

最大權閉合子圖,正權點向s連一條容量為權值的邊,負權點向t連一條容量為權值的相反數的邊,

每個被保護的點向保護它的點連一條容量為

inf的邊。

然後tarjan

找出圈,圈裡的就是那些無敵的植物。但不僅僅是圈裡的植物是無敵的,

還要找出所有可以到達圈的點,這些點也都是無敵的,這裡調了幾個小時。把無敵的植物去掉後重新建圖。

1 #include

2 #include3 #include4 #include5 #include6 #include7 #include

8 #include9 #include10 #include11 #include12 #include13 #include14

#define inf 1999999999

15using

namespace

std;

16struct

datae[8000010],g[8000010

];19

int po[35][35],head[1000],edge=-1,lev[1000],head1[1000],edge1=-1;20

int dfn[1000],low[1000],scc[1000],kp[1000],bj[1000],bj1[1000],sccno=0;21

bool ppp[1000

];22 stacks;

23 inline void add(int

from,int to,int

w)30 inline void add1(int

from,int to,int

w)37

int de=0;bool ff=0;38

void tarjan(int

x)49

else

if(!scc[u]) low[x]=min(low[x],dfn[u]);50}

51if(dfn[x]==low[x])

58 kp[sccno]++;

59 scc[x]=sccno;

60if(!s.empty())s.pop();61}

62}63 inline bool bfs(int s,int

t)77}78

return0;

79}80int dfs(int s,int t,int

k)91

if(!tag)lev[s]=0;92

return

tag;93}

94 inline int dinic(int s,int

t)99

void dfs1(int

x)104

for(int i=head[x];i!=-1;i=e[i].nex)

105if(e[i].w>0

) dfs1(e[i].to);

106}

107int

main()

108127

for(int i=0;i)

128for(int j=0;j1;j++)

129 add(po[i][j],po[i][j+1],inf),add(po[i][j+1],po[i][j],0

);130

for(int i=0;i<=t;i++)

131if(!scc[i]) tarjan(i);

132for(int i=s;i<=t;i++)

133if(kp[scc[i]]>1) bj[i]=1

;134

for(int i=1;i)

135if(!bj[i])

140for(int i=s;i<=t;i++)

141for(int j=head[i];j!=-1;j=e[j].nex)

142if(!bj[e[j].from] && !bj[e[j].to] && e[j].w>0) add1(e[j].from,e[j].to,e[j].w),add1(e[j].to,e[j].from,0

);143

for(int i=head1[s];i!=-1;i=g[i].nex)

144 ans+=g[i].w;

145int lol=ans-dinic(s,t);

146 printf("

%d",max(lol,0

));147

return0;

148 }

NOI2009 植物大戰殭屍

這道題跟noi2006 最大獲利其實是很像的 一樣都是要搞定一些點才能搞定另一些點,然後有些點正權有些點負權 這種問題,其實是最大權閉合子圖 amber的最小割 有詳細的講解法和證明 閉合子圖的定義是,圖中每個點所連線的的任何一條邊不指向圖外,可以有邊指向這個圖 這實際上就是乙個依賴關係,如果我們把...

NOI 2009 植物大戰殭屍

plants vs.zombies pvz 是最近十分風靡的一款小遊戲。plants 植物 和 zombies 殭屍 是遊戲的主角,其中 plants 防守,而 zombies 進攻。該款遊戲包含多種不同的挑戰系列,比如 protect your brain bowling 等等。其中最為經典的,莫...

NOI2009 植物大戰殭屍

這道題跟noi2006 最大獲利其實是很像的 一樣都是要搞定一些點才能搞定另一些點,然後有些點正權有些點負權 這種問題,其實是最大權閉合子圖 amber的最小割 有詳細的講解法和證明 閉合子圖的定義是,圖中每個點所連線的的任何一條邊不指向圖外,可以有邊指向這個圖 這實際上就是乙個依賴關係,如果我們把...