3697 採藥人的路徑

2022-05-12 09:56:46 字數 2381 閱讀 3958

採藥人的藥田是乙個樹狀結構,每條路徑上都種植著同種藥材。

採藥人以自己對藥材獨到的見解,對每種藥材進行了分類。大致分為兩類,一種是陰性的,一種是陽性的。

採藥人每天都要進行採藥活動。他選擇的路徑是很有講究的,他認為陰陽平衡是很重要的,所以他走的一定是兩種藥材數目相等的路徑。採藥工作是很辛苦的,所以他希望他選出的路徑中有乙個可以作為休息站的節點(不包括起點和終點),滿足起點到休息站和休息站到終點的路徑也是陰陽平衡的。他想知道他一共可以選擇多少種不同的路徑。

第1行包含乙個整數n。

接下來n-1行,每行包含三個整數a_i、b_i和t_i,表示這條路上藥材的型別。

輸出符合採藥人要求的路徑數目。

71 2 0

3 1 1

2 4 0

5 2 0

6 3 1

5 7 1

1對於100%的資料,n ≤ 100,000。

第一次寫點分治。。。

黃學長的題解:

來自出題人hta的題解。。

本題可以考慮樹的點分治。問題就變成求過根滿足條件的路徑數。

路徑上的休息站一定是在起點到根的路徑上,或者根到終點的路徑上。

如何判斷一條從根出發的路徑是否包含休息站?只要在dfs中記錄下這條路徑的和x,同時用個標誌陣列判斷這條路徑是否存在字首和為x的節點。

這樣我們列舉根節點的每個子樹。用f[i][0…1],g[i][0…1]分別表示前面幾個子樹以及當前子樹和為i的路徑數目,0和1用於區分路徑上是否存在字首和為i的節點。那麼當前子樹的貢獻就是f[0][0] * g[0][0] + σf [i][0] * g [-i][1] + f[i][1] * g[-i][0] + f[i][1] * g[-i][1],其中i的範圍[-d,d],d為當前子樹的深度。

1 #include2 #include3 #include4 #include5 #include6 #include7 #include

8 #include9 #include10 #include11 #include

12#define inf 1000000000

13#define maxn 100005

14#define maxm 200005

15#define eps 1e-10

16#define ll long long

17#define for0(i,n) for(int i=0;i<=(n);i++)

18#define for1(i,n) for(int i=1;i<=(n);i++)

19#define for2(i,x,y) for(int i=(x);i<=(y);i++)

20#define for3(i,x,y) for(int i=(x);i>=(y);i--)

21#define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)

22using

namespace

std;

23int

read()

26while(ch>='

0'&&ch<='9')

27return x*f;28}

29int

n,tot,sum,rt,mxdeep;

30bool

vis[maxm];

31int

t[maxm],mx[maxn],fa[maxn],size[maxn],deep[maxn],d[maxn],head[maxn];

32 ll ans,g[maxm][2],f[maxm][2

];33

struct

edgee[maxm];

36void insert(int u,int v,int

w)40

void getroot(int x,int

fa)48

}49 mx[x]=max(mx[x],sum-size[x]);

50if(mx[x]x;51}

52void dfs(int x,int

fa)63

}64 t[d[x]]--;65}

66void cal(int

x)82}83

}84for(int i=n-mx;i<=n+mx;i++)g[i][0]=g[i][1]=0;85

for4(i,x)92}

93}94int

main()

103 sum=mx[0]=n;

104 getroot(1,0

);105

cal(rt);

106 printf("

%lld

",ans);

107return0;

108 }

view code

3697 採藥人的路徑

題目鏈結 題目大意 一棵樹,邊權為0 1,求有多少路徑滿足01個數相等,且存在乙個點 不能為起點或終點 這個點到起點和終點分別滿足01個數相等 題解 澱粉質點分治 ore menci 我的收穫 澱粉質!include using namespace std const int n 100005 co...

BZOJ3697 採藥人的路徑

給定一棵樹,找一些路徑滿足,路徑上0,1數量相等,並在路徑上找到乙個點 休息站 改點到路徑兩端上0,1數量也相等,同一條路徑點不同,記為不同,詢問有多少條路徑滿足條件 點分治 對於乙個點 u 我們遍歷每棵子樹中的節點 v,求出di s u,v 我們記錄這條路徑上有無節點 t 使得di s v,t 0...

bzoj3697 採藥人的路徑

這是個思路題,對我這樣的zz 來說可能已經接近自己想出來的極限了。一看統計符合條件的路徑條數,肯定是點分治,而且肯定是靜態的。首先把邊權變成 1 和 1 那麼一條路徑陰陽平衡也就是說它的權值和等於 0 根據點分治的過程,可知重心和路徑是一對多的關係,而且一條路徑只會對應乙個重心,就是說每條路徑都只會...