码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 5102 The K-th Distance (队列+生成法,,)

时间:2014-11-09 15:07:22      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   ar   sp   div   log   代码   bs   

题意:

N个点的一棵树。定义点u和点v的距离等于它们之间的路径(唯一的)的长度。这样我们可以得到n*(n-1)/2个距离。

将它们从小到大排序,问前K个数的和是多少。

 

思路:

将边长为1的树枝都入队列。每次取出一个,然后从这根树枝的前端生出一个新点,变成距离加1的一根新树枝,将其入队列。如此操作下去。

可得到所有的各种长度的树枝。因为每根树枝其实有两个在队列里(互为方向生长),故求前2*K个数的和,然后除以2。

*:我们取前队列里的前2K个,就算后面的若干些不是一对一对的,也一定可以取2K个以后的一些数与这2K个数的一些交换,将2K个数调整为一对一对的形式。(画个样例想想就明白了)

例子:

1-2-3          树枝: (1->2),(2->1),(2->3),(3->2),(1->2->3),(3->2->1)

 

代码:(*:生成够2K个数就可以及时退出了,不然TLE)

struct node{
    int u,v,len;
}edge[2000100];

vector<int> graph[100100];

int T,n,k;

int main(){
    cin>>T;
    while(T--){
        scanf("%d%d",&n,&k);
        int c=0;
        rep(i,1,n) graph[i].clear();
        rep(i,1,n-1){
            int x,y;
            scanf("%d%d",&x,&y);
            graph[x].push_back(y);
            graph[y].push_back(x);
            edge[++c].u=x, edge[c].v=y, edge[c].len=1;
            edge[++c].v=x, edge[c].u=y, edge[c].len=1;
        }
        int p=0;
        while(p<=c){
            if(c>=2*k) break;
            ++p;
            int U=edge[p].u, V=edge[p].v;
            int L=graph[U].size();
            rep(i,0,L-1) if(graph[U][i]!=V && c<2*k){
                ++c;
                edge[c].u=graph[U][i];
                edge[c].v=U;
                edge[c].len=edge[p].len+1;
            }
        }
        ll ans=0;
        int ts=min(c,2*k);
        rep(i,1,ts) ans+=(ll)edge[i].len;
        printf("%I64d\n",ans/2);
    }
}

 

hdu 5102 The K-th Distance (队列+生成法,,)

标签:style   blog   color   ar   sp   div   log   代码   bs   

原文地址:http://www.cnblogs.com/fish7/p/4085116.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!