1565植物大戰殭屍

2021-08-07 05:58:13 字數 1929 閱讀 8712

description

input

output

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

sample input

3 210 0

20 0

-10 0

-5 1 0 0

100 1 2 1

100 0

sample output

hint

在樣例中, 植物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 。

這道題:乙個經典的最大權閉合子圖問題,就是之前要把那些一定幹不掉的環給topo一遍刪光。

我的dinic寫法太醜導致超時,後來發現dinic在深蒐時可以加一句話防止多餘的操作。

if(!res) dis[x] = -1;

很強的乙個剪枝剪完就過了。

具體見**。

//dinic的優化。 

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int n = 3005;

const

int m = 300005;

int ne[m] , to[m] , cnt = 1 , c[m] , dis[n] , fir[n] , res , s , t , du[n] , r , c , score[n] , ans;

bool inq[n] , die[n];

vector

g[n];

int pos[55][35] , tot;

int getpos(int x ,int y)

void add(int x,int y , int z)

#define foreachson(i,x) for(int i = fir[x];i;i = ne[i])

#define getdirection int v = to[i];

void link(int x ,int y ,int z)

bool bfs(int s ,int t)

}return (dis[t] != -1);

}int dfs(int x ,int fl,int t)

if(!fl) break;

}if(!res) dis[x] = -1;

return res;

}int maxflow(int s,int t)

return res;

}void toposort() }}

// for(int i = 1;i <= getpos(r,c);i ++) if(die[i]) cerr

void build()

else link(s,i, -score[i]);

for(int j = 0;j

}}int main()

for(int k = 1;k <= num;k ++) }}

toposort();

build();

printf("%d\n", ans - maxflow(s,t));

}

bzoj1565 植物大戰殭屍

題目鏈結 如果想消滅掉乙個植物,那麼必須先消滅掉左右能保護這個植物的植物。這就成了最大權閉合子圖的模板題了。有兩個需要注意的地方。第乙個就是,能保護當前植物的植物還有當前植物右面的所有植物。第二個就是,在環裡的植物或者是被在環裡的植物所保護的植物是無法消滅的。所以先拓撲一下,找出所有可能被消滅的植物...

BZOJ 1565 植物大戰殭屍

思路 由於植物之間有保護關係 右邊的植物保護左邊的植物,植物攻擊範圍內的植物都被保護了 因此可以用最大權閉合子圖。1 include2 include3 include4 include5 include6 define inf 0x7fffffff 7struct edgee 500005 10 ...

1565 NOI2009 植物大戰殭屍

題面 很裸的乙個最大權閉合子圖啊。如果依賴關係有環,活著說他的依賴關係和環有關,就把這個點廢掉。然後你就構圖跑最大權閉合子圖就好了 include include include include include using namespace std const int n 23 33 const ...