小x游世界树

Posted monyhzc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小x游世界树相关的知识,希望对你有一定的参考价值。

题源

技术图片 


 Input

7
7 8 1 3 2 5 2
4 6 5
6 1 8
1 2 9
5 4 3
3 4 10
3 7 4

Output

1 24

一看就知道是个什么套路

记录每个点的siz , dis。在父子节点间考虑转移。

然后搞了个代码,过了个极水的样例

 1 #include<stdio.h>
 2 #define For(i,a,b) for(register int i=(a);i<=(b);i++)
 3 using namespace std;
 4 const int maxn=7e5+10;
 5 int n,a[maxn],head[maxn],cnt,siz[maxn],dis[maxn],ans=1;
 6 long long del[maxn],tot;
 7 struct Edge{
 8     int v,nxt,w;
 9 }edge[maxn<<1];
10 inline void add(int u,int v,int w){
11     edge[++cnt].v=v,edge[cnt].w=w,edge[cnt].nxt=head[u],head[u]=cnt;
12 }
13 inline void pre(int p,int fa){
14     siz[p]=1,tot+=dis[p];
15     for(int i=head[p];i;i=edge[i].nxt){
16         int v=edge[i].v;if(v==fa) continue;
17         dis[v]=dis[p]+edge[i].w;
18         pre(v,p);siz[p]+=siz[v];
19     }
20 }
21 inline void dfs(int p,int fa){
22     for(int i=head[p];i;i=edge[i].nxt){
23         int v=edge[i].v;if(v==fa) continue;
24         del[v]=del[fa]+(n-siz[v])*edge[i].w-siz[v]*edge[i^1].w;
25         dfs(v,p);
26     }
27 }
28 signed main(){
29     scanf("%d",&n);
30     For(i,1,n) scanf("%d",&a[i]);
31     For(i,2,n){
32         int b,c,d;scanf("%d%d%d",&b,&c,&d);
33         add(b,c,d-a[b]),add(c,b,d-a[c]);
34     }
35     pre(1,1);
36     dfs(1,1);
37     For(i,1,n){
38         if(del[i]<del[ans]) ans=i;
39     }
40     printf("%d %d
",ans,tot+del[ans]);
41 }

然后爆0。比如上面那个数据就没过去。

发现算法没错。

 int cnt; 

从零开始的cnt竟然用^1来搞反向边,我……

然后再来一发,爆了int

呃呃呃我开了long long啊

 printf("%d %d ",ans,del[ans]); 

改成lld, A了,我……

 1 #include<stdio.h>
 2 #define For(i,a,b) for(register int i=(a);i<=(b);i++)
 3 using namespace std;
 4 const int maxn=7e5+10;
 5 int n,a[maxn],head[maxn],cnt=1,siz[maxn],ans=1;
 6 long long dis[maxn],del[maxn];
 7 struct Edge{
 8     int v,nxt,w;
 9 }edge[maxn<<1];
10 inline void add(int u,int v,int w){
11     edge[++cnt].v=v,edge[cnt].w=w,edge[cnt].nxt=head[u],head[u]=cnt;
12 }
13 inline void pre(int p,int fa){
14     siz[p]=1,del[1]+=dis[p];
15     for(int i=head[p];i;i=edge[i].nxt){
16         int v=edge[i].v;if(v==fa) continue;
17         dis[v]=dis[p]+edge[i].w;
18         pre(v,p);
19         siz[p]+=siz[v];
20     }
21 }
22 inline void dfs(int p,int fa){
23     for(int i=head[p];i;i=edge[i].nxt){
24         int v=edge[i].v;if(v==fa) continue;
25         del[v]=del[p]+(n-siz[v])*edge[i^1].w-(siz[v])*edge[i].w;
26         dfs(v,p);
27     }
28 }
29 signed main(){
30     scanf("%d",&n);
31     For(i,1,n) scanf("%d",&a[i]);
32     For(i,2,n){
33         int b,c,d;scanf("%d%d%d",&b,&c,&d);
34         add(b,c,d-a[b]),add(c,b,d-a[c]);
35     }
36     pre(1,1);
37     dfs(1,1);
38     For(i,1,n){
39         if(del[i]<del[ans]) ans=i;
40     }
41     printf("%lld %lld
",ans,del[ans]);
42 }

发现能A的和原来没有多大差别

我是沙雕

技术图片

以上是关于小x游世界树的主要内容,如果未能解决你的问题,请参考以下文章

JZOJ5776 小x游世界树

小x游世界树

张书乐:影游联动故事还能继续吗?完美世界与游戏大佬们的IP链困局

小代码 圣诞节树的打印

魔幻世界手游理财制度开发

UOJ207 共价大爷游长沙