hdu 5102  spfa的思想---队列的使用

首先最短的路径一定是各条边,然后是两条边组成的路径,所以我们可以利用宽搜的思想,利用队列每次取一条边,然后对它进行拓展,直到选够边数为止,用一个变量求和即可.

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <queue>
#define MAX 100007

using namespace std;

int t,n,k,u,v;

struct Edge 
{
    int v,next;
}e[MAX<<1];

struct Path
{
    int u,v,l,pre;
    Path ( int a , int b , int c , int d )
        : u(a),v(b),l(c),pre(d)
    {}
};

typedef long long LL;

int head[MAX];
int cc = 0;

void add ( int u , int v )
{
    e[cc].v =v;
    e[cc].next = head[u];
    head[u] = cc++;
}

int main ( )
{
    scanf ( "%d" , &t );
    while ( t-- )
    {
        queue<Path> q;
        LL ans = 0;
        cc = 0;
        memset ( head , -1 , sizeof ( head ) );
        scanf ( "%d%d" , &n , &k );
        for ( int i = 1 ; i < n ; i++ )
        {
            scanf ( "%d%d" , &u , &v );
            add ( u , v );
            add ( v , u );
            q.push ( Path ( u , v , 1 , u) );
            q.push ( Path ( v , u , 1 , v ) );
        }
        int cnt = 0 ;
        while ( cnt < k*2 )
        {
            int x = q.front().u , y = q.front().v;
            int l = q.front().l , pre = q.front().pre;
            ans += l;
           // cout << cnt << " : " << l << endl;
            cnt++;
            if ( cnt >= k*2 ) break;
            q.pop();
            if ( q.size() + cnt > k*2 ) continue;
            for ( int i = head[y] ; i != -1 ; i = e[i].next )
            {
                int v = e[i].v;
                if ( v == pre ) continue;
                q.push ( Path ( x , v , l+1 , y ) );
            }
        }
        printf ( "%I64d\n" , ans/2 );
    }
}


你可能感兴趣的:(数据结构,C++,队列)