• (树dp)UVA


    题目链接

    题意:两个国家A,B,分别有N座城市和Q座城市(1 ≤ N, Q ≤ 4 × 10^4),每个国家里的城市都是树形结构,每条边的权值都是1。现在要随机从两个国家中各选择一个城市来将两个国家连接起来,问连接起来的大国家里面的最长路的期望是多少。

    解题思路:

    涉及到树上的最大长度,很容易想到树的直径。首先分别求出两棵树的直径, 之后就很方便的可以求出树上每个结点只在树上走的最大距离。这样对于任意一个连法,假设链接了xy,最大距离=max(两棵树的直径中的最大值,x在该树中最大距离+y在该树中最大距离+1)

    减少时间复杂度可以通过排序距离的办法。

    (代码非常丑……)

      1 #include <iostream>
      2 #include <string>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <cstdio>
      6 #include <cmath>
      7 #include <queue>
      8 #include <set>
      9 #include <map>
     10 #include <list>
     11 #include <stack>
     12 #define mp make_pair
     13 typedef long long ll;
     14 typedef unsigned long long ull;
     15 const int MAX=1e5+5;
     16 const int INF=1e9+5;
     17 const double M=4e18;
     18 using namespace std;
     19 const int MOD=1e9+7;
     20 typedef pair<int,int> pii;
     21 typedef pair<int,long long> pil;
     22 const double eps=0.000000001;
     23 int n;
     24 vector<pii> edge[MAX],edge2[MAX];
     25 ll sum[MAX];
     26 int a,b;
     27 ll c;
     28 ll d[MAX],d2[MAX];
     29 bool vi[MAX];
     30 int lo1,lo2,lo3,lo4;
     31 int oh,oh2;
     32 int findlong(int st)
     33 {
     34     memset(vi,false,sizeof(vi));
     35     vi[st]=true;
     36     queue<pii> que;
     37     int dismax=0,dis;
     38     int an,tem;
     39     que.push(mp(st,0));
     40     while(!que.empty())
     41     {
     42         tem=que.front().first;
     43         dis=que.front().second;
     44         pii lin;
     45         que.pop();
     46         for(int i=0;i<edge[tem].size();i++)
     47         {
     48             lin=edge[tem][i];
     49             if(!vi[lin.first])
     50             {
     51                 vi[lin.first]=true;
     52                 if(dismax<dis+lin.second)
     53                 {
     54                     dismax=dis+lin.second;
     55                     an=lin.first;
     56                 }
     57                 que.push(mp(lin.first,dis+lin.second));
     58             }
     59         }
     60     }
     61     oh=dismax;
     62     return an;
     63 }
     64 int findlong2(int st)
     65 {
     66     memset(vi,false,sizeof(vi));
     67     vi[st]=true;
     68     queue<pii> que;
     69     int dismax=0,dis;
     70     int an,tem;
     71     que.push(mp(st,0));
     72     while(!que.empty())
     73     {
     74         tem=que.front().first;
     75         dis=que.front().second;
     76         pii lin;
     77         que.pop();
     78         for(int i=0;i<edge2[tem].size();i++)
     79         {
     80             lin=edge2[tem][i];
     81             if(!vi[lin.first])
     82             {
     83                 vi[lin.first]=true;
     84                 if(dismax<dis+lin.second)
     85                 {
     86                     dismax=dis+lin.second;
     87                     an=lin.first;
     88                 }
     89                 que.push(mp(lin.first,dis+lin.second));
     90             }
     91         }
     92     }
     93     oh2=dismax;
     94     return an;
     95 }
     96 void dfs(int st)
     97 {
     98     memset(vi,false,sizeof(vi));
     99     vi[st]=true;
    100     queue<pii> que;
    101     int tem;
    102     int dis;
    103     que.push(mp(st,0LL));
    104     while(!que.empty())
    105     {
    106         tem=que.front().first;
    107         dis=que.front().second;
    108         pii lin;
    109         que.pop();
    110         d[tem]=max(d[tem],(ll)dis);
    111         for(int i=0;i<edge[tem].size();i++)
    112         {
    113             lin=edge[tem][i];
    114             if(!vi[lin.first])
    115             {
    116                 vi[lin.first]=true;
    117                 que.push(mp(lin.first,dis+lin.second));
    118             }
    119         }
    120     }
    121 }
    122 void dfs2(int st)
    123 {
    124     memset(vi,false,sizeof(vi));
    125     vi[st]=true;
    126     queue<pii> que;
    127     int tem;
    128     int dis;
    129     que.push(mp(st,0LL));
    130     while(!que.empty())
    131     {
    132         tem=que.front().first;
    133         dis=que.front().second;
    134         pii lin;
    135         que.pop();
    136         d2[tem]=max(d2[tem],(ll)dis);
    137         for(int i=0;i<edge2[tem].size();i++)
    138         {
    139             lin=edge2[tem][i];
    140             if(!vi[lin.first])
    141             {
    142                 vi[lin.first]=true;
    143                 que.push(mp(lin.first,dis+lin.second));
    144             }
    145         }
    146     }
    147 }
    148 ll finan;
    149 int main()
    150 {
    151         int n,q;
    152         while(~scanf("%d %d",&n,&q))
    153         {
    154             oh=oh2=0;
    155             for(int i=1;i<=n;i++)
    156                 d[i]=0LL,edge[i].clear();
    157             for(int i=1;i<=q;i++)
    158                 d2[i]=0LL,edge2[i].clear();
    159             for(int i=1;i<n;i++)
    160             {
    161                 scanf("%d%d",&a,&b);
    162                 edge[a].push_back(mp(b,1));
    163                 edge[b].push_back(mp(a,1));
    164             }
    165             for(int i=1;i<q;i++)
    166             {
    167                 scanf("%d%d",&a,&b);
    168                 edge2[a].push_back(mp(b,1));
    169                 edge2[b].push_back(mp(a,1));
    170             }
    171             if(n==1)
    172                 lo1=lo2=1;
    173             if(n>1)
    174             {
    175                 lo1=findlong(1);
    176                 lo2=findlong(lo1);
    177             }
    178             if(q==1)
    179                 lo3=lo4=1;
    180             if(q>1)
    181             {
    182                 lo3=findlong2(1);
    183                 lo4=findlong2(lo3);
    184             }
    185             dfs(lo1);dfs(lo2);
    186             dfs2(lo3);dfs2(lo4);
    187             sort(d+1,d+1+n);
    188             sort(d2+1,d2+1+q);
    189             for(int i=1;i<=n;i++)
    190                 ++d[i];
    191             sum[0]=0LL;
    192             for(int i=1;i<=q;i++)
    193                 sum[i]=sum[i-1]+d2[i];
    194             ll idx=q+1;
    195             ll len=max(ll(oh),ll(oh2));
    196             ll re=0;
    197             for(int i=1;i<=n;i++)
    198             {
    199                 while(idx-1>=1&&d2[idx-1]+d[i]>len)
    200                     --idx;
    201                 if(idx==1)
    202                     re+=sum[q]+q*d[i];
    203                 else if(idx==q+1)
    204                     re+=len*q;
    205                 else
    206                 {
    207                     re+=len*(idx-1);
    208                     re+=sum[q]-sum[idx-1]+(q-idx+1)*d[i];
    209                 }
    210             }
    211             printf("%.3f
    ",(double)re/n/q);
    212         }
    213         return 0;
    214 }
  • 相关阅读:
    对象继承习题
    Java访问修饰符(转)
    对Java JVM中类加载几点解释
    1006 最长公共子序列Lcs
    算法训练 成绩的等级输出
    算法训练 统计字符次数
    算法训练 连接字符串
    算法训练 筛选号码
    算法训练 十进制数转八进制数
    算法训练 斜率计算
  • 原文地址:https://www.cnblogs.com/quintessence/p/6993693.html
Copyright © 2020-2023  润新知