[每日一题]4.2 Shortest Path

Shortest Path

http://www.nowcoder.com/questionTerminal/f1d38ddf05124dc9898280431349fad9

  • 题意:给出一棵有偶数的节点的树,将其分成n/2对点,并且要求n/2对点的路径之和最小

  • 涉及知识点:思维/树上dfs

  • 思路:树上任意两点间的距离是唯一的,题目又要求路径之和最小,所以选择两个节点,要么是父节点和其孩子节点,要么是父节点的两个孩子节点,还有一种情况是多了一个孩子节点,那么肯定要先加上到父节点的距离,然后再和另外一个节点配对。
    所以在树上dfs,枚举子树的节点个数,一颗子树如果节点个数为偶数,就不需要再添加节点配对,如果节点个数为奇数,需要和父节点往外的一个节点配对,那么答案就要加上这颗子树到父节点的距离

  • 代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int maxn = 10005;
    struct node{
      int t,nex;
      ll w;
    };
    node a[maxn<<1];
    int head[maxn],tot,cnt[maxn];
    ll ans ;
    void add(int x,int y,ll z){
      a[++tot].t = y,a[tot].nex = head[x],a[tot].w = z,head[x] = tot;
    }
    void dfs(int x,int fath,ll w)
    {
      cnt[x] = 1;
      for(int i=head[x] ; i ; i = a[i].nex){
          if(a[i].t != fath){
              dfs(a[i].t , x , a[i].w);
              cnt[x] += cnt[a[i].t];
          }
      }
      if(cnt[x]%2)
          ans += w;
    }
    int main()
    {
      int t;
      cin>>t;
      while(t--)
      {
          tot = 0,ans = 0;
          int n,x,y;
          scanf("%d",&n);
          memset(cnt, 0 ,sizeof(cnt));
          memset(head , 0,sizeof(head));
          for(int i=1;i<n;i++){
              ll z;
              cin>>x>>y>>z;
              add(x, y, z),add(y, x, z);
          }
          dfs(1 , 0 , 0);
          cout<<ans<<endl;
      }
      return 0;
    }
    

```

acm菜鸡日常 文章被收录于专栏

一般写一些打过的比赛题解以及不会的算法

全部评论

相关推荐

找工作勤劳小蜜蜂:自我描述部分太差,完全看不出想从事什么行业什么岗位,也看不出想在哪个地区发展,这样 会让HR很犹豫,从而把你简历否决掉。现在企业都很注重员工稳定性和专注性,特别对于热爱本行业的员工。 你实习的工作又太传统的it开发(老旧),这部分公司已经趋于被淘汰,新兴的互联网服务业,比如物流,电商,新传媒,游戏开发和传统的It开发有天然区别。不是说传统It开发不行,而是就业岗位太少,基本趋于饱和,很多老骨头还能坚持,不需要新血液。 工作区域(比如长三角,珠三角,成渝)等也是HR考虑的因素之一,也是要你有个坚定的决心。否则去几天,人跑了,HR会被用人单位骂死。
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务