BZOJ1565 NOI2009 植物大戰殭屍

2022-05-11 04:04:24 字數 3071 閱讀 4424

problem

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在本題的設定中,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

25

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

//乙個方案為,首先進攻p1,1, p0,1,此時可以攻擊p0,0 。

//共得到能源收益為(-5)+20+10 = 25。

//注意, 位置(2,1)被植物p2,0保護,所以無法攻擊第2行中的任何植物。

依舊是乙個最大權閉合子圖模型

要選中左側的植物,就必須要選中右側的植物,連邊

要選中被保護的植物,就要選中保護該植物的植物,連邊

原關係圖上是可能會有環的,顯然在環上的點都不能被選中

這髒比怎麼這麼菜連綁緊跳殭屍都沒有

因此我們在轉化為網路流圖前,需要跑一邊tarjan找環

然後就可以愉快地dinic了

又長又臭的**,慎讀

#include #include #include #include #include #include #include #define maxn 25

#define maxm 35

using namespace std;

typedef long long ll;

template void read(t &t)

while(isdigit(c))

if(f)t=-t;

}const int inf=0x3f3f3f3f;

int n,m;

int s,t,ans;

int p[maxn*maxm];

struct edge

g[maxn*maxn*maxm*maxm];

int head[maxn*maxm],ecnt=1;

void eadd(int u,int v,int w)

int dep[maxn*maxm];

bool bfs()

} return false;

}int dfs(int u,int infl)

rest-=flow;

g[i].w-=flow;

g[i^1].w+=flow;

} return infl-rest;

}inline int trans(int r,int c)

int dfn[maxn*maxm],low[maxn*maxm],sign;

int stk[maxn*maxm],top,ins[maxn*maxm];

int inr[maxn*maxm];

void tarjan(int u)

else if(ins[v])

low[u]=min(low[u],dfn[v]);

} if(dfn[u]==low[u])

inr[stk[top]]=flag;

ins[stk[top--]]=0; }}

int main()

while(bfs())

ans-=dfs(s,inf);

printf("%d",ans);

return 0;

}

bzoj1565 NOI2009 植物大戰殭屍

傳送門 這道題吃到某個植物a可能需要先吃掉別的植物b 在他的右邊或者保護著他 那麼我們把a連向b。發現這是最大權閉合子圖。顯然是可以通過網路流水過的。閉合子圖 v中頂點的所有出邊均指向v內部頂點 那麼按照最大權閉合圖的建圖方法 1.s向正權點連流量為權值的邊 2.負權點向t連流量為權值的絕對值的邊 ...

BZOJ1565 NOI2009 植物大戰殭屍

好久沒寫部落格了 題目在這裡 沒什麼好說的 應該很容易看出是最大閉合子圖吧?不過要注意一下的是,這題可能有植物是不可能被擊潰的,所以要先跑一遍拓撲排序把這些點排除掉 include include include include include include include include usi...

Bzoj1565 NOI2009 植物大戰殭屍

time limit 10 sec memory limit 64 mb submit 2363 solved 1092 僅包含乙個整數,表示可以獲得的最大能源收入。注意,你也可以選擇不進行任何攻擊,這樣能源收入為0。3 210 0 20 0 10 0 5 1 0 0 100 1 2 1 100 0...