• luogu P1268 树的重量


    一开始把这题想复杂了,,,

    这里记(di[i][j])表示(i)(j)的距离

    首先如果(n=2),答案显然为(di[1][2])

    如果(n=3)

    233

    懒得画图了盗图过来

    那么3号点会从1,2号点的路径上伸出去,相比较(n=2),答案多出了(frac{di[1][3]+di[2][3]-di[1][2]}{2})

    (n=4)的情况

    233

    如果把4看做从1,2号点路径上伸出去的,那么答案(红色部分)会算重一部分;把4看做从1,3号点路径上伸出去的,那么答案(蓝色部分色部分)则是正确的,同时我们也发现蓝色比红色短

    以此类推,每次插入一个点(i),把它依次看做从1,(j(1<j<i))号点路径上伸出去的,然后答案加上(min(frac{di[1][i]+di[j][i]-di[1][j]}{2})).取min才不会和前面的答案算重

    其实我一开始考虑记录每条路径上哪个位置伸出去什么点,麻烦的死

    #include<bits/stdc++.h>
    #define LL long long
    #define il inline
    #define re register
    
    using namespace std;
    const int N=1000000+10;
    il LL rd()
    {
        re LL x=0,w=1;re char ch;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int n,di[40][40];
    
    int main()
    {
      while(1)
        {
          n=rd();
          if(n==0) break;
          for(int i=1;i<=n;i++) di[i][i]=233;
          for(int i=1;i<=n;i++)
    		for(int j=i+1;j<=n;j++)
    	  	di[i][j]=di[j][i]=rd();
          int ans=di[1][2];
          for(int i=3;i<=n;i++)
    	    {
    	      int an=233;
    	      for(int j=2;j<i;j++) an=min(an,(di[1][i]+di[i][j]-di[1][j])>>1);
    	      ans+=an;
    	    }
          printf("%d
    ",ans);
        }
      return 0;
    }
    
  • 相关阅读:
    jQuery遍历之siblings()
    命名空间
    AnsiString
    《linux内核完全注释》读书笔记 2
    mciSendString
    PeekMessage, GetMessage, PostMessage, SendMessage
    c/c++中运行外部程序或打开文件(转)
    定义基类和派生类
    复制构造函数
    让StringGrid控件显示下拉菜单
  • 原文地址:https://www.cnblogs.com/smyjr/p/9478404.html
Copyright © 2020-2023  润新知