多校3 hdu6060 RXD and dividing

来源:互联网 发布:电视mac认证状态异常 编辑:程序博客网 时间:2024/06/17 01:09

先记录每个节点与哪些节点相连接,把1当做根节点dfs一遍找到每个节点有多少子节点(包括子节点的子节点),并记录当前节点与其父节点连边的权值。

枚举2—n节点,计算其于父节点连边的贡献,相加得到答案。

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <vector>#define mod 1000000007using namespace std;int e;inline long long mini(long long a, long long b){if (a < b){return a;}return b;}int vis[1000000+5];struct node{    long long son,fw;}q[2000005];int head[2000000+5];struct nn{    int v,next;    long long w;}ed[2000000+5];void add(int u,int v,int w){     ed[e].v = v; ed[e].w = w;     ed[e].next = head[u];     head[u] = e ++;}long long  dfs(int x){    long long ans = 0;    int flag = 0;    vis[x] = 1;   for(int i = head[x]; i != -1; i = ed[i].next)   {       int tx = ed[i].v;       if(vis[tx]) continue;       q[tx].fw =ed[i].w;       flag =1;       ans += dfs(tx);   }    if(!flag)    {        q[x].son = 0;       return 1;    }    else    {        q[x].son = ans;       return ans+1;    }}int main(){    int n;    long long m;   while(~scanf("%d%lld",&n,&m))   {       memset(q,0,sizeof(q));       memset(head,-1,sizeof(head));       memset(vis,0,sizeof(vis));       e = 0;       for(int i = 0; i < n-1; i++)       {           int u,b,ww;           scanf("%d%d%d",&u,&b,&ww);          add(u,b,ww); add(b,u,ww);       }       dfs(1);       long long ans = 0;       for(int i = 2; i <= n; i++)       {           if(q[i].son)           ans = ans +      q[i].fw*mini(m,q[i].son + 1);           else            ans += q[i].fw;          //  cout << i << "     " << ans <<endl;       }       printf("%lld\n",ans);   }}

原创粉丝点击