HNOI2015 落憶楓音

2022-08-25 22:27:27 字數 1581 閱讀 9158

description

input

output

sample input

輸入1:

4 4 4 3

1 21 3

2 43 2

輸入2:

10 16 7 2

1 21 8

2 32 4

3 53 6

4 54 6

5 76 7

7 10

8 48 6

8 99 6

9 10

sample output

輸出1:

3

輸出2:

92

data constraint

首先有乙個重要結論!

對於乙個有向無環圖(dag),它的生成樹個數就等於除根外所有點入度的乘積!

我考試的時候不知道這玩意然後直接gg了。。。

然後我們加入了一條邊,可能會形成環,有環仍按以上方法計算會有不合法的情況,那麼我們用總方案減去不合法的方案即是ans

不合法方案的環中一定會包含我們新加入的邊x->y

那麼假設環中剩餘的路徑y->x,那麼形成這樣的環的方案數即為,總數/(在路徑上的點的入度積),因為在路徑上的點入度只能選路徑上的邊,其他的點仍可以隨便選,

除法用逆元處理,那麼我們設g[i]為所有y到i路徑上的點的逆元的路的總和,按拓撲序dp一遍求出g[x]即可

#include#include

#include

#include

#include

using

namespace

std;

typedef

long

long

ll;int mo=1000000007

;int du[100011],fc[100011],g[100011],next[200011],y[200011],que[200011

];int

l,r,x,j,k,n,m,tx,ty,z,i,ans,tt,la;

int f[100011

];void star(int i,int

j)int mi(int x,int

z)

returnl;}

intmain()

if(tx==ty||ty==1

)

else

l=r=1

; que[l]=1

;

while(l<=r)

j=next[j];

}l++;

}f[ty]=fc[ty];

l=r=1

; que[l]=ty;

while(l<=r)

j=next[j];

}l++;

}la=(ll)la*f[tx]%mo;

ans=ans-la;

ans=(ans%mo+mo)%mo;

printf(

"%d\n

",ans);}}

HNOI2015 落憶楓音

hnoi2015 落憶楓音 首先 原圖是乙個dag 生成樹即為除了根節點以外每個節點隨便選一條入邊組成的 所以生成樹數量 各個點入度乘積 新加入一條邊 分三種情況 1.如果不成環 那麼可以把它放在原來的dag裡計算 2.如果它的終點為1 那麼忽略不計 3.如果它成環的話 假設其中乙個環大小是size...

HNOI2015 落憶楓音

嘟嘟嘟 這題大意就是有乙個dag,然後新增了一條邊,求上有多少種生成樹。這題想了半天,最後還是寫了暴力。暴力就是 o 2 mn 的那種,還出鍋了幾次 剛開始我不想dfs判斷選出的邊是否構成樹,於是yy了一下,以為只要邊數為 n 1 除了根節點每個點的入度為1且都被訪問過就行了。卻忘了有環的情況 只要...

HNOI2015 落憶楓音

luogu3244 bzoj4011 如果是乙個dag,那麼答案顯然是 prod n deg i 其中 deg i 是點 i 的入度。加上條邊後可能會成環,我們要去掉成環的情況數。考慮乙個環,錯誤的計數只會發生在環上每個點選了自己環上的父親,環外的點隨意。所以對於每個環,多餘的計數是 prod de...