标签:des style blog http io color ar os java
2 3 3 1 2 2 3 5 7 1 2 1 3 2 4 2 5
4 10
给定一个n个节点的树,求路径长度前k大的所有路径和。
题解方法:把所有边(u,v) 以及(v,u)放入一个队列,队列每弹出一个元素(u,v),对于所有与u相邻的点w,如果w!=v,就把(w,u)入队。这样就能一个一个生成前K小的距离。注意到每条边实际上会入队两次,只要把K翻倍且把ans除2即可,时间复杂度为O(n+K)
由于思路简单,就懒得写代码了,直接抄了yyn代码:
#include <map> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std ; typedef long long LL ; #define rep( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i ) #define For( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i ) #define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i ) #define clr( a , x ) memset ( a , x , sizeof a ) const int MAXN = 100005 ; const int MAXE = 200005 ; struct Node { int v , p , d ; Node () {} Node ( int v , int p , int d ) : v ( v ) , p ( p ) , d ( d ) {} } ; struct Edge { int v , n ; Edge () {} Edge ( int v , int n ) : v ( v ) , n ( n ) {} } ; Node Q[3000005] ; Edge E[MAXE] ; int H[MAXN] , cntE ; int head , tail ; LL ans ; int n , k ; void clear () { ans = 0 ; cntE = 0 ; clr ( H , -1 ) ; } void addedge ( int u , int v ) { E[cntE] = Edge ( v , H[u] ) ; H[u] = cntE ++ ; } void bfs () { int cnt = 0 ; head = tail = 0 ; For ( i , 1 , n ) Q[tail ++] = Node ( i , 0 , 0 ) ; while ( head != tail ) { Node x = Q[head ++] ; int u = x.v , p = x.p ; for ( int i = H[u] ; ~i ; i = E[i].n ) { int v = E[i].v ; if ( v != p ) { Q[tail ++] = Node ( v , u , x.d + 1 ) ; ans += x.d + 1 ; //printf ( "%d->%d %d %d\n" , u , v , cnt , x.d + 1 ) ; ++ cnt ; if ( cnt == k ) return ; } } } } void solve () { int u , v ; clear () ; scanf ( "%d%d" , &n , &k ) ; k *= 2 ; rep ( i , 1 , n ) { scanf ( "%d%d" , &u , &v ) ; addedge ( u , v ) ; addedge ( v , u ) ; } bfs () ; printf ( "%I64d\n" , ans / 2 ) ; } int main () { int T ; scanf ( "%d" , &T ) ; while ( T -- ) solve () ; return 0 ; }
代码:
/* *********************************************** Author :rabbit Created Time :2014/11/9 12:03:22 File Name :H.cpp ************************************************ */ #pragma comment(linker, "/STACK:102400000,102400000") #include <stdio.h> #include <iostream> #include <algorithm> #include <sstream> #include <stdlib.h> #include <string.h> #include <limits.h> #include <string> #include <time.h> #include <math.h> #include <queue> #include <stack> #include <set> #include <map> using namespace std; #define INF 0x3f3f3f3f #define eps 1e-8 #define pi acos(-1.0) typedef long long ll; const int maxn=100100; int head[maxn],tol; int size[maxn],vis[maxn],fa[maxn],que[maxn]; int num[maxn],ans[maxn]; int maxd,TT; struct Edge{ int next,to; }edge[3*maxn]; inline void addedge(int u,int v){ edge[tol].to=v; edge[tol].next=head[u]; head[u]=tol++; } inline int getroot(int u){ int Min=maxn,root=0; int l,r; que[l=r=1]=u;fa[u]=u; for(;l<=r;l++) for(int i=head[que[l]];i!=-1;i=edge[i].next){ int v=edge[i].to; if(v==fa[que[l]]||vis[v]==TT)continue; que[++r]=v; fa[v]=que[l]; } for(l--;l;l--){ int x=que[l],Max=0; size[x]=1; for(int i=head[x];i!=-1;i=edge[i].next){ int v=edge[i].to; if(v==fa[x]||vis[v]==TT)continue; Max=max(Max,size[v]); size[x]+=size[v]; } Max=max(Max,r-size[x]); if(Max<Min){ Min=Max;root=x; } } return root; } int dis[maxn]; int Q[1001000],S[500100]; inline void go(int root){ int tot=0; for(int i=head[root];i!=-1;i=edge[i].next){ int u=edge[i].to; if(vis[u]==TT)continue; fa[u]=root; dis[u]=1; int l,r,cnt=0; que[l=r=1]=u; for(;l<=r;l++){ int x=que[l]; ans[dis[x]]++; Q[cnt++]=dis[x]; for(int j=1;j<=maxd;j++) if(j+dis[x]<=maxd)ans[j+dis[x]]+=num[j]; for(int j=head[x];j!=-1;j=edge[j].next){ int v=edge[j].to; if(v==fa[x]||vis[v]==TT||dis[x]+1>maxd)continue; dis[v]=dis[x]+1; fa[v]=x; que[++r]=v; } } for(int j=0;j<cnt;j++){ if(!num[Q[j]])S[tot++]=Q[j]; num[Q[j]]++; } } for(int i=0;i<tot;i++)num[S[i]]=0; } inline void solve(int u){ int root=getroot(u); vis[root]=TT; go(root); for(int i=head[root];i!=-1;i=edge[i].next){ int v=edge[i].to; if(vis[v]==TT)continue; solve(v); } } int main() { //freopen("data.in","r",stdin); //freopen("data.out","w",stdout); int T,n,k; cin>>T; memset(vis,0,sizeof(vis)); while(T--){ scanf("%d%d",&n,&k); maxd=min(k/n+50,k); memset(head,-1,sizeof(head));tol=0; memset(num,0,sizeof(num)); memset(ans,0, sizeof(ans)); TT++; for(int i=1;i<n;i++){ int u,v; scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } solve(1); ll sum=0; for(int i=1;i<=maxd;i++){ if(ans[i]>=k){ sum+=(ll)k*i; break; } k-=ans[i]; sum+=(ll)ans[i]*i; } printf("%I64d\n",sum); } return 0; }
标签:des style blog http io color ar os java
原文地址:http://blog.csdn.net/xianxingwuguan1/article/details/40949323