P2805 NOI2009 植物大戰殭屍

2022-09-24 05:12:10 字數 1451 閱讀 4210

給定乙個 \(n\) 行 \(m\) 列的圖,每個點可以保護一些點。

每個點有乙個權值(可以為負數)。

如果要選取乙個點則必須選取保護它的點以及它右邊的點。

試求最大權值和(可以乙個點也不選)。

\(1 \leq n \leq 20,1\leq m\leq 30\),時限 \(1\text\),空限 \(125\text\)。

sol容易發現這其實是一道最大權閉合子圖的題。

但是需要注意:圖可能有環。

也就是說如果你遇到一些植物相互保護的話,是無解的。

所以我們可以用拓撲排序來找出所有的環,在拓撲排序過程中訪問到的點才有實際意義。

最後跑一遍最大權閉合子圖即可。

#include using namespace std;

inline int read()

while (c >= '0' && c <= '9')

return x * f;

}inline void write(int x)

if (x > 9)

write(x / 10);

putchar(x % 10 + '0');

}typedef int tp;

const int _ = 5e5 + 10;

int n, m, s, t, lv[_], cur[_];

int tot = 1, head[_], to[_ << 1], nxt[_ << 1];

tp w[_ << 1];

inline void add(int u, int v, tp dis)

inline void add(int u, int v, tp dis)

inline bool bfs()

} return lv[t] != -1;

}tp dfs(int p = s, tp flow = 2e9)

} return flow - rmn;

}inline tp dinic()

int id(int x, int y)

bool vis[_];

int in[_], score[_];

vectorout[_];

void toposort()

while (!q.empty())

} }}

signed main()

if (j < m)

}toposort();

s = 0, t = _ - 1;

int sum = 0;

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

else

add(u, t, -score[u]);

for (int k = 0; k < out[u].size(); k++)

}} write(sum - dinic());

return 0;

}

p2805 NOI2009 植物大戰殭屍

傳送門 分析 我們知道乙個點可以保護他射程的那幾個點和他左邊的那個點 我們又知道如果保護關係成環則環中的點以及這些點左面的點均是無敵的 所以我們按保護關係連邊,然後跑tarjan 然後只要找出點數大於1的聯通塊中的點即可 之後問題就轉換為了求無敵點之外的點所構成圖的最大權閉合子圖 注意此處是正權點連...

P1589 NOI2009 植物大戰殭屍

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

NOI2009 植物大戰殭屍

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