Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 6232 | Accepted: 1770 |
Description
Input
Output
Sample Input
5 4 1 2 3 1 3 1 1 4 2 3 5 1 0 0
Sample Output
8
----------------------------------------------------------------
题目大意:见漆子超论文。
解题思路:见漆子超论文。表示一A,爽歪歪,原来是这样子的,还是觉得挺暴力的,只是避免了最坏情况而已。
#include <stdio.h> #include <string.h> #include <algorithm> #include <queue> #define clr(a,b) memset(a,b,sizeof(a)) using namespace std; const int N=10005,M=20005,inf=0x3f3f3f3f; int n,lim,eid,minn; int head[N],ed[M],val[M],nxt[M]; int vis[N],fa[N],siz[N],dep[N],le,ri; void addedge(int s,int e,int v){ ed[eid]=e;val[eid]=v;nxt[eid]=head[s];head[s]=eid++; } int dfssize(int s,int f){ fa[s]=f;siz[s]=1; for(int i=head[s];~i;i=nxt[i]) if(ed[i]!=f&&!vis[ed[i]])siz[s]+=dfssize(ed[i],s); return siz[s]; } void dfsroot(int s,int sum,int&root){ int maxx=sum-siz[s]; for(int i=head[s];~i;i=nxt[i]){ int e=ed[i];if(e==fa[s]||vis[e])continue; dfsroot(e,sum,root);maxx=max(maxx,siz[e]); } if(maxx<minn){minn=maxx;root=s;} } void dfsdepth(int s,int d,int f){ dep[ri++]=d; for(int i=head[s];~i;i=nxt[i]) if(ed[i]!=f&&!vis[ed[i]])dfsdepth(ed[i],d+val[i],s); } int getdep(int a,int b){ sort(dep+a,dep+b);int ret=0,e=b-1; for(int i=a;i<b;i++){ if(dep[i]>lim)break; while(e>=a&&dep[e]+dep[i]>lim)e--; ret+=e-a+1;if(e>i)ret--; } return ret>>1; } int solve(int s){ int sum=dfssize(s,-1),ret=0;minn=inf; int root;dfsroot(s,sum,root); vis[root]=1; for(int i=head[root];~i;i=nxt[i]) if(ed[i]!=root&&!vis[ed[i]]) ret+=solve(ed[i]); le=ri=0; for(int i=head[root];~i;i=nxt[i]) if(ed[i]!=root&&!vis[ed[i]]){ dfsdepth(ed[i],val[i],-1);ret-=getdep(le,ri);le=ri; } ret+=getdep(0,ri); for(int i=0;i<ri;i++) if(dep[i]<=lim)ret++; else break; // printf("%d %d %d %d\n",root,ret,le,ri); vis[root]=0; return ret; } int main(){ // freopen("/home/axorb/in","r",stdin); while(scanf("%d%d",&n,&lim),n+lim){ eid=0;clr(head,-1); for(int i=1;i<n;i++){ int a,b,c;scanf("%d%d%d",&a,&b,&c); addedge(a,b,c);addedge(b,a,c); } clr(vis,0); printf("%d\n",solve(1)); } }