hdu 5102(队列+节点扩展)

来源:互联网 发布:知乎 日韩军力对比 编辑:程序博客网 时间:2024/06/03 19:18

The K-th Distance

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)


Problem Description
Given a tree, which has n node in total. Define the distance between two node u and v is the number of edge on their unique route. So we can have n(n-1)/2 numbers for all the distance, then sort the numbers in ascending order. The task is to output the sum of the first K numbers.
 

Input
There are several cases, first is the number of cases T. (There are most twenty cases).
For each case, the first line contain two integer n and K (2n100000,0Kmin(n(n1)/2,106) ). In following there are n-1 lines. Each line has two integer u , v. indicate that there is an edge between node u and v.
 

Output
For each case output the answer.
 

Sample Input
23 31 22 35 71 21 32 42 5
 

Sample Output
410
解题思路:这道题一开始的想法就是bfs,因为bfs是按层次来扩展节点,可以算出每个节点到根节点的距离。但关键就是两点之间的距离如果没有横跨根节点,这里想了好久,一直没有办法解决。看了别人的思路,说实话很难想到,用一个队列维护即可,先将所有边入队,然后不停的用边的一个端点向外扩张,每扩张一次,路径长度就+1
由于1->2和2->1会重复算,所以K要扩大一倍,那么最后的结果肯定会多算一倍,除以2即可。
#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;#define N 100007struct node{    int u,v,d;    node(int _u,int _v,int _d):u(_u),v(_v),d(_d){}    node(){}};struct Edge{    int v,next;}G[2*N];int ans,k,tot,head[N];queue<node> q;void addedge(int u,int v){    G[tot].v = v;    G[tot].next = head[u];    head[u] = tot++;}void bfs(){    int cnt = 0;    while(!q.empty())    {        node tmp = q.front();        q.pop();        int u = tmp.u, v = tmp.v, d = tmp.d;        if(cnt >= k) break;        for(int i = head[u]; i != -1; i = G[i].next)        {            int vv = G[i].v;            if(vv != v)            {                ans += d+1;                cnt++;                q.push(node(vv,u,d+1));            }            if(cnt >= k) break;        }    }}int main(){    int t,n,u,v,i;    scanf("%d",&t);    while(t--)    {        while(!q.empty()) q.pop();        scanf("%d%d",&n,&k);        tot = 0;        memset(head,-1,sizeof(head));        for(i = 1; i <= n; i++) q.push(node(i,i,0));        for(i = 1; i < n; i++)        {            scanf("%d%d",&u,&v);            addedge(u,v);            addedge(v,u);        }        k *= 2;        ans = 0;        bfs();        cout<<ans/2<<endl;    }    return 0;}


0 0
原创粉丝点击