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 #include2 #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的最小割 有詳細的講解法和證明 閉合子圖的定義是,圖中每個點所連線的的任何一條邊不指向圖外,可以有邊指向這個圖 這實際上就是乙個依賴關係,如果我們把...