阿公尺巴是小強的好朋友。
阿公尺巴和小強在草原上捉螞蚱。小強突然想,如果螞蚱被他們捉滅絕了,那麼吃螞蚱的小鳥就會餓死,而捕食小鳥的猛禽也會跟著滅絕,從而引發一系列的生態災難。
學過生物的阿公尺巴告訴小強,草原是乙個極其穩定的生態系統。如果螞蚱滅絕了,小鳥照樣可以吃別的蟲子,所以乙個物種的滅絕並不一定會引發重大的災難。
我們現在從專業一點的角度來看這個問題。我們用一種叫做食物網的有向圖來描述生物之間的關係:
乙個食物網有n個點,代表n種生物,如果生物x可以吃生物y,那麼從y向x連乙個有向邊。
這個圖沒有環。
圖中有一些點沒有連出邊,這些點代表的生物都是生產者,可以通過光合作用來生存; 而有連出邊的點代表的都是消費者,它們必須通過吃其他生物來生存。
如果某個消費者的所有食物都滅絕了,它會跟著滅絕。
我們定義乙個生物在食物網中的「災難值」為,如果它突然滅絕,那麼會跟著一起滅絕的生物的種數。
舉個例子:在乙個草場上,生物之間的關係是:
如
如果小強和阿公尺巴把草原上所有的羊都給嚇死了,那麼狼會因為沒有食物而滅絕,而小強和阿公尺巴可以通過吃牛、牛可以通過吃草來生存下去。所以,羊的災難值是1。但是,如果草突然滅絕,那麼整個草原上的5種生物都無法倖免,所以,草的災難值是4。
給定乙個食物網,你要求出每個生物的災難值。
乙個生物滅絕僅當它的所有食物都滅絕了,而所有食物都滅絕僅當他們的lca滅絕,因此我們把每個生物都連線在它的所有食物的lca上,即每個節點的父節點是它的所有食物的lca。按這樣建樹還有乙個條件,就是這個生物加入之前它的所有食物都加入了,所以要按拓撲序加點,最後統計一下樹上字首和。
#include
using
namespace
std;
const
int maxn = 100000 + 10;
int n,deg[maxn],dep[maxn],father[maxn][25],size[maxn];
vector
edge1[maxn],edge2[maxn],tree[maxn];
queue
q;inline
intlca
(int a,int b)
return father[a][0];
}inline
void
dfs(int now,int fa)
}int
main
() dep[n+1] = 1;
for (int i = 1;i <= n;i++)
if (!deg[i])
while (q.size())
}dfs(n+1,0);
for (int i = 1;i <= n;i++) printf("%d\n",size[i]-1);
return
0;}
#include
using
namespace
std;
const
int maxn = 100000 + 10;
int n,deg[maxn],dep[maxn],father[maxn][25],size[maxn];
vector
edge1[maxn],edge2[maxn],tree[maxn];
queue
q;inline
intlca
(int a,int b)
return father[a][0];
}inline
void
dfs(int now,int fa)
}int
main
() dep[n+1] = 1;
for (int i = 1;i <= n;i++)
if (!deg[i])
while (q.size())
}dfs(n+1,0);
for (int i = 1;i <= n;i++) printf("%d\n",size[i]-1);
return
0;}
省選專練ZJOI2012旅遊
stl在開o2後自然是大水題。考點 樹的直徑。第一二次構圖。把每乙個三角塊相鄰的建邊。怎麼建?stl 你都做到這個題了map hash兩個值鐵定會吧。但是zjoi沒有那麼好心,不過你也有70分了。於是這樣 把兩點建邊。排個序。相同的時候連起來。樹的直徑。很多人求複雜了。樹的直徑一遍dfs就可以,不需...
bzoj2815 災難 拓撲排序 lca
按照出題人的題解 我們需要構造一顆 滅絕樹 即對於滅絕樹上的兩個點x,y,如果x為y的祖先,則x的滅亡會直接導致y的滅亡。下面進行構造 首先進行拓撲排序,然後按照排序的逆序構造,保證對於圖中的任意x 都能使x構造前,已經完成構造。然後找到在滅絕樹上面的位置,顯然在滅絕樹上的公共祖先的滅絕會導致全部滅...
ZJOI2012網路 題解報告 LCT
有乙個無向圖g,每個點有個權值,每條邊有乙個顏色。這個無向圖滿足以下兩個條件 對於任意節點連出去的邊中,相同顏色的邊不超過兩條。圖中不存在同色的環,同色的環指相同顏色的邊構成的環。在這個圖上,你要支援以下三種操作 修改乙個節點的權值。修改一條邊的顏色。查詢由顏色c的邊構成的圖中,所有可能在節點u到節...