码迷,mamicode.com
首页 > 其他好文 > 详细

小x游世界树

时间:2020-01-14 20:24:42      阅读:74      评论:0      收藏:0      [点我收藏+]

标签:lin   targe   开始   can   line   inline   register   ble   output   

题源

技术图片 


 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\n",ans,tot+del[ans]);
41 }

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

发现算法没错。

 int cnt; 

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

然后再来一发,爆了int

呃呃呃我开了long long啊

 printf("%d %d\n",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\n",ans,del[ans]);
42 }

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

我是沙雕

技术图片

小x游世界树

标签:lin   targe   开始   can   line   inline   register   ble   output   

原文地址:https://www.cnblogs.com/monyhzc/p/12193651.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!