zoukankan      html  css  js  c++  java
  • hdu 4118 dfs

    题意:给n个点,每个点有一个人,有n-1条有权值的边,求所有人不在原来位置所移动的距离的和最大值。不能重复

    这题的方法很有看点啊,标记为巩固题

    Sample Input
    1
    4
    1 2 3
    2 3 2
    4 3 2
     
    Sample Output
    Case #1: 18    //1去4,4去1,2去3,3去2
     

    对于每条边,因为大家都想走的最远,那么相当于让边两端的人交换,花费就是 边长*经过边的人数

    ans = Σ (每条路长 l )*(经过这条路的最大次数 f )

    f = 2 * 这条边左边节点数和右边节点数最小值k. (这样左边的每一个点一定能够对应右边的某个点)

    这个k可以dfs 求得.

    hdu用c++交,g++会爆栈

      1 #pragma comment(linker, "/STACK:10240000000000,10240000000000")
      2 #include<stdio.h>
      3 #include<algorithm>
      4 #include<iostream>
      5 #include<string.h>
      6 using namespace std;
      7 const int MAXN=200010;
      8 struct Node
      9 {
     10     int to,next;
     11     int len;
     12 }edge[MAXN*2];
     13 
     14 int head[MAXN];
     15 int tol;
     16 int num[MAXN];//从这个点以下的结点数
     17 long long ans;
     18 void init()
     19 {
     20     tol=0;
     21     memset(head,-1,sizeof(head));
     22     memset(num,0,sizeof(num));
     23 }
     24 void add(int a,int b,int len)
     25 {
     26     edge[tol].to=b;
     27     edge[tol].len=len;
     28     edge[tol].next=head[a];
     29     head[a]=tol++;
     30 
     31     edge[tol].to=a;
     32     edge[tol].len=len;
     33     edge[tol].next=head[b];
     34     head[b]=tol++;
     35 }
     36 int n;
     37 //递归形式会超出内存
     38 void dfs(int u,int pre)
     39 {
     40     for(int i=head[u];i!=-1;i=edge[i].next)
     41     {
     42         int v=edge[i].to;
     43         if(v==pre)continue;
     44         dfs(v,u);
     45         num[u]+=num[v];
     46         ans+=(long long)edge[i].len*min(num[v],n-num[v]);
     47     }
     48     num[u]++;
     49 }
     50 
     51 /*int sta[MAXN];
     52 bool vis[MAXN];
     53 void dfs(int u)
     54 {
     55     memset(vis,false,sizeof(vis));
     56     int top=0;
     57     sta[top++]=u;
     58     vis[u]=true;
     59     while(top>0)
     60     {
     61         bool flag=true;
     62         int t=sta[top-1];
     63         for(int i=head[t];i!=-1;i=edge[i].next)
     64         {
     65             int v=edge[i].to;
     66             if(vis[v])continue;
     67             flag=false;
     68             sta[top++]=v;
     69             vis[v]=true;
     70         }
     71         if(!flag)continue;
     72         top--;
     73         for(int i=head[t];i!=-1;i=edge[i].next)
     74         {
     75             int v=edge[i].to;
     76             if(num[v]!=0)
     77             {
     78                 num[t]+=num[v];
     79                 ans+=(long long)edge[i].len*min(num[v],n-num[v]);
     80             }
     81         }
     82         num[t]++;
     83     }
     84 }*/
     85 
     86 int main()
     87 {
     88     int T;
     89     int iCase=0;
     90     int u,v,w;
     91     #ifndef ONLINE_JUDGE
     92     freopen("1.in","r",stdin);
     93     #endif
     94     scanf("%d",&T);
     95     while(T--)
     96     {
     97         iCase++;
     98         scanf("%d",&n);
     99         init();
    100         ans=0;
    101         for(int i=1;i<n;i++)
    102         {
    103             scanf("%d%d%d",&u,&v,&w);
    104             add(u,v,w);
    105         }
    106         dfs(1,0);
    107         printf("Case #%d: %I64d
    ",iCase,ans*2);
    108     }
    109     return 0;
    110 }
  • 相关阅读:
    面试容易问到的Linux问题
    Java面试题复习笔记(框架)
    Java面试题复习笔记(前端)
    Java面试题复习笔记(数据库)
    Java面试题复习笔记(Web方向)
    【刷题-LeetCode】191 Number of 1 Bits
    【数学】随机方法计算逆矩阵
    【刷题-LeetCode】190 Reverse Bits
    【刷题-LeetCode】188 Best Time to Buy and Sell Stock IV
    python 30 面向对象之 多态
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4417237.html
Copyright © 2011-2022 走看看