• hdu 4303 Hourai Jeweled 夜


    http://acm.hdu.edu.cn/showproblem.php?pid=4303

    算法有时候不是关键 关键在于思维能力

    这个题 一遍DFS就可以 不需要多复杂的算法

    但是需要较好的思维能力 才能在一遍DFS的情况下搞定左右情况的值

    自己是思维就是不行呀 看了提示才过的

    但是 不知道是因为 64位整型 和int型  相乘相加时会出问题 还是题目的一些数据大小的范围出问题啦

    纠结了n久 最后把一些int 都改成64位 就过了 是不是其他问题我也不知道

    这个题我是没法说思路啦 因为我已经挂了 呜呜呜呜呜~~~~~~~~~

    代码:

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<cmath>
    #include<stack>
    #include<algorithm>
    #define LL long long
    
    using namespace std;
    
    const int N=300005;
    
    struct node
    {
        int uppath;
        LL num;
        LL upnum;
        struct tt *next;
    }mem[N];
    struct tt
    {
        int j;
        int color;
        struct tt *next;
    };
    struct aa
    {
        int x,y;
        int color;
    }edge[N];
    int value[N];
    bool cmp(aa a,aa b)
    {
        return a.color>b.color;
    }
    void build(int i,int j,int color)
    {
        struct tt *t=new tt;
        t->j=j;
        t->color=color;
        t->next=mem[i].next;
        mem[i].next=t;
    }
    void Dele(int n)
    {
        for(int i=1;i<=n;++i)
        mem[i].next=NULL;
    }
    void Dfs(int x,int pre,int precolor)
    {
        struct tt *t=mem[x].next;
        mem[x].num=0;
        mem[x].uppath=1;
        mem[x].upnum=value[x];
        LL ldifsum=0,lsum=0;
        LL updifsum=0,upsum=0;
        LL lnum=0;
        int lcolor=0;
        while(t!=NULL)
        {
            if(t->j==pre)
            {t=t->next;continue;}
            Dfs(t->j,x,t->color);
            if(t->j!=pre&&t->color!=precolor)
            {
                mem[x].uppath+=mem[t->j].uppath;
                mem[x].upnum+=(mem[t->j].upnum+value[x]*mem[t->j].uppath);
            }
            if(t->color!=lcolor)
            {
                ldifsum=lsum;
                updifsum=upsum;
            }
            mem[x].num+=(value[x]*(mem[t->j].uppath*ldifsum)+(mem[t->j].uppath*value[x])+mem[t->j].upnum);
            lnum+=(mem[t->j].uppath*updifsum+mem[t->j].upnum*ldifsum);
            lsum+=mem[t->j].uppath;
            lcolor=t->color;
            upsum+=mem[t->j].upnum;
            t=t->next;
        }
        mem[x].num+=lnum;
    }
    int main()
    {
       //freopen("data.txt","r",stdin);
       int n;
       while(scanf("%d",&n)!=EOF)
       {
           for(int i=1;i<=n;++i)
           {
               scanf("%d",&value[i]);
           }
           for(int i=0;i<n-1;++i)
           {
               scanf("%d %d %d",&edge[i].x,&edge[i].y,&edge[i].color);
           }
           sort(edge,edge+n-1,cmp);
           for(int i=0;i<n-1;++i)
           {
               build(edge[i].x,edge[i].y,edge[i].color);
               build(edge[i].y,edge[i].x,edge[i].color);
           }
           Dfs(1,0,0);
           LL ans=0;
           for(int i=1;i<=n;++i)
           {
               ans+=mem[i].num;
           }
           cout<<ans<<endl;
           Dele(n);
       }
    }
    

      

  • 相关阅读:
    JS替换字符
    sql 两个表字段叠加
    Qt实现窗口半透明显示
    Qt 设置窗口属性setWindowFlags函数
    ARM-Linux按键和旋钮控制
    飞凌开发板OK335xD烧写Linux镜像总结
    Qt QGraphics类应用——图片移动+选点缩放+控制移动区域
    Qt QGraphics类应用——地图缩放选点
    Ubuntu 同时使用有线和无线(有线连开发板,无限上网)
    Qt 自定义控件提升,头文件找不到的问题
  • 原文地址:https://www.cnblogs.com/liulangye/p/2603061.html
Copyright © 2020-2023  润新知