zoukankan      html  css  js  c++  java
  • 10.30T3 换根

    Description

      在幻想乡,藤原妹红是拥有不老不死能力的人类。虽然不喜欢与人们交流,妹红仍然保护着误入迷途竹林村民。由于妹红算得上是幻想乡最强的人类,对于她而言,迷途竹林的单向道路亦可以逆行。在妹红眼中,迷途竹林可以视为一个由N个路口(编号1..N),M条不同长度双向路连接的区域。妹红所在的红之自警队为了方便在迷途竹林中行动,绘制了一张特殊的迷途竹林地图,这张地图上只保留了N-1条道路,这些道路保证了任意两个路口间有且仅有一条路径,并且满足所有保留的道路长度之和最小,我们称这些道路为『自警队道路』。现在妹红打算在其中一个连接有多条『自警队道路』的路口设立根据地,当去掉这个根据地所在路口后,就会出现某些路口间无法通过『自警队道路』相互连通的情况,我们认为这时仍然能够通过『自警队道路』连通的路口属于同一个『区域』。妹红希望最后每个『区域』的『自警队道路』总长尽可能平均,请计算出她应该选择哪一个路口作为根据地。 
      下例中红色的路口为妹红选择的根据地,实线边表示『自警队道路』,绿色虚线边表示非『自警队道路』,数字表示边权,『自警队道路』中相同颜色的实线边代表属于同一个『区域』:

      

      (尽可能平均即权值最小,设每一块『区域』的路线总长为 Length[i],平均路线长度为Avg=SUM{Length[i]}/区域数,权值d=∑((Length[i]-Avg)^2))

    Input

      第1行:2个正整数N,M。
      第2..M+1行:每行2个整数u,v和1个实数len,表示u,v之间存在长度为len的边。

    Output

      第1行:1个整数,最后选择的路口编号,存在多个可选路口时选择编号小的。

    Sample Input

    3 3
    3 1 5
    3 2 4
    1 2 3

    Sample Output

    2

    Hint

    【样例解释】
      妹红的『固定道路』为(1,2)和(2,3)。只能选择2作为根据地,产生的两个区域Length[i]分别为3和4,所以方差为:(4-3.5)^2+(3-3.5)^2=0.5
    【数据范围】
      对于60%的数据:3≤N≤2,000,N-1≤M≤50,000 
      对于100%的数据:3≤N≤40,000,N-1≤M≤200,000 
      对于100%的数据:0 < len ≤ 100,000,000 
    【注意】
      保证不存在相同距离的线路,两个路口间可能出现多条路径,且任意点对间至少存在一条路径。
     
     
     
     
    简单的预处理子树里面的权值和然后直接换根就可以了
    code:
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #define N 100005
     6 using namespace std;
     7 struct node {
     8     double u,v;
     9     double w;
    10 } e[N],t[N];
    11 int first[N],nxt[N],cnt;
    12 void add(int u,int v,double w) {
    13     e[++cnt].u=u;
    14     e[cnt].v=v;
    15     e[cnt].w=w;
    16     nxt[cnt]=first[u];
    17     first[u]=cnt;
    18 }
    19 double f[N];
    20 double sumtree=0;
    21 double find(int x) {
    22     if(x!=f[x])return f[x]=find(f[x]);
    23     return f[x];
    24 }
    25 void merge(int x,int y) {
    26     int f1=find(x),f2=find(y);
    27     if(f1!=f2) {
    28         f[f1]=f2;
    29     }
    30 }
    31 int n,m;
    32 void kruskal() {
    33     double cnt_=0;
    34     for(int i=1; i<=m; i++) {
    35         double u=t[i].u,v=t[i].v;
    36         if(find(u)!=find(v)) {
    37             merge(u,v);
    38             cnt_++;
    39             add(u,v,t[i].w);
    40             add(v,u,t[i].w);
    41             sumtree+=t[i].w;
    42             if(cnt_==n-1)return;
    43         }
    44     }
    45 }
    46 double siz[N];
    47 double fa[N];
    48 void dfs1(int x){
    49     siz[x]=0;
    50     for(int i=first[x];i;i=nxt[i]){
    51         siz[x]+=e[i].w;
    52         int v=e[i].v;
    53         if(v==fa[x])continue;
    54         fa[v]=x;
    55         dfs1(v);
    56         siz[x]+=siz[v];
    57     }
    58 }
    59 void dfs2(int x){
    60     double child[10005];int tot=0;
    61     for(int i=first[x];i;i=nxt[i]){
    62         int v=e[i].v;
    63         if(v==fa[x])continue;
    64         child[++tot]=siz[v]+e[i].w;
    65     }
    66     if(tot==0)return;
    67     if(x!=1){
    68         child[++tot]=sumtree-siz[x];
    69     }
    70     double avg=sumtree/tot;
    71     double d=0;
    72     for(int i=1;i<=tot;i++){
    73         d+=(child[i]-avg)*(child[i]-avg);
    74     }
    75     if(d<min0)
    76 }
    77 bool cmp(const node&a,const node&b) {
    78     return a.w<b.w;
    79 }
    80 int main() {
    81     cin>>n>>m;
    82     for(int i=1; i<=n; i++)f[i]=i;
    83     for(int i=1; i<=m; i++) {
    84         cin>>t[i].u>>t[i].v>>t[i].w;
    85     }
    86     sort(t+1,t+m+1,cmp);
    87     kruskal();///
    88     dfs1(1);
    89     dfs2(1);
    90     cout<<ID;
    91     return 0;
    92 }

    over

  • 相关阅读:
    ListView的优化
    RotateAnimation详解
    Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace.
    Java 完美判断中文字符的方法
    详细解析Java中抽象类和接口的区别
    Android中如何实现多行、水平滚动的分页的Gridview?
    Android实现多页左右滑动效果,支持子view动态创建和cache
    android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
    Android TextView文字横向自动滚动(跑马灯)
    android自定义TabWidget样式
  • 原文地址:https://www.cnblogs.com/saionjisekai/p/9879286.html
Copyright © 2011-2022 走看看