Tree POJ - 174

点分模板题

都快改的跟题解一模一样了2333333

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 using namespace std;
  5 struct E
  6 {
  7     int to,nxt,d;
  8 }e[20100];
  9 int f1[10100],ne;
 10 bool vis[10100];
 11 int n,k,root,sz[10100],fx[10100],sum,ans;
 12 //sum:当前连通块节点总数
 13 int dep[10100],tmp[10100];
 14 void getroot(int x,int fa)
 15 //获取x所在连通块内的根
 16 {
 17     sz[x]=1;fx[x]=0;
 18     for(int k=f1[x];k;k=e[k].nxt)
 19         if(!vis[e[k].to]&&e[k].to!=fa)
 20         {
 21             getroot(e[k].to,x);
 22             sz[x]+=sz[e[k].to];
 23             fx[x]=max(fx[x],sz[e[k].to]);
 24         }
 25     fx[x]=max(fx[x],sum-sz[x]);
 26     if(fx[x]<fx[root])    root=x;
 27 }
 28 void getsz(int x,int fa)
 29 //处理出当前连通块的大小
 30 {
 31     sz[x]=1;
 32     for(int k=f1[x];k;k=e[k].nxt)
 33         if(!vis[e[k].to]&&e[k].to!=fa)
 34         {
 35             getsz(e[k].to,x);
 36             sz[x]+=sz[e[k].to];
 37         }
 38 }
 39 void getdeep(int u,int fa)
 40 {
 41     tmp[++tmp[0]]=dep[u];
 42     for(int k=f1[u];k;k=e[k].nxt)
 43         if(!vis[e[k].to]&&e[k].to!=fa)
 44         {
 45             dep[e[k].to]=dep[u]+e[k].d;
 46             getdeep(e[k].to,u);
 47         }
 48 }
 49 int cal(int u,int cost)
 50 {
 51     dep[u]=cost;tmp[0]=0;
 52     getdeep(u,0);
 53     sort(tmp+1,tmp+tmp[0]+1);
 54     int l,r,sum=0;
 55     r=tmp[0]+1;
 56     for(l=1;l<=tmp[0];l++)
 57     {
 58         while(r>1&&tmp[r-1]>k-tmp[l])    r--;
 59         if(l>=r)    break;
 60         sum+=(r-l-1);
 61     }
 62     return sum;
 63 }
 64 void solve(int u)
 65 //解决u所在连通块的问题,u作为该块的根
 66 {
 67     ans+=cal(u,0);vis[u]=1;
 68     for(int k=f1[u];k;k=e[k].nxt)
 69         if(!vis[e[k].to])
 70         {
 71             ans-=cal(e[k].to,e[k].d);
 72             root=0;
 73             getsz(e[k].to,0);sum=sz[e[k].to];
 74             getroot(e[k].to,0);
 75             solve(root);
 76         }
 77 }
 78 int main()
 79 {
 80     int i,u,v,l;
 81     fx[0]=0x3f3f3f3f;
 82     while(1)
 83     {
 84         memset(f1,0,sizeof(f1));ne=ans=0;
 85         memset(vis,0,sizeof(vis));
 86         scanf("%d%d",&n,&k);
 87         if(n==0&&k==0)    break;
 88         for(i=1;i<n;i++)
 89         {
 90             scanf("%d%d%d",&u,&v,&l);
 91             e[++ne].to=v;e[ne].nxt=f1[u];e[ne].d=l;f1[u]=ne;
 92             e[++ne].to=u;e[ne].nxt=f1[v];e[ne].d=l;f1[v]=ne;
 93         }
 94         sum=n;
 95         getroot(1,0);
 96         solve(root);
 97         printf("%d\n",ans);
 98     }
 99     return 0;
100 }
posted @ 2018-03-14 21:40  hehe_54321  阅读(196)  评论(0编辑  收藏  举报
AmazingCounters.com