• P3806 【模板】点分治1(CDQ分治)


    题目链接:https://www.luogu.org/problemnew/show/P3806

    题目大意:中文题目

    具体思路:直接dfs好像会超时,然后我们就开始想优化的方法,然后就是一个CDQ入门题了,我们可以分解成许多子问题进行解决,然后对于一棵树的话,我们最好的切入点就是这棵树的重心了,这样就能使得复杂度尽可能的低了,然后就不停的往下递归找每一棵子树的重心进行求解就可以了,然后注意去重。

    AC代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 # define ll long long
      4 # define inf 0x3f3f3f3f
      5 const int maxn = 1e6+100;
      6 # define inf 0x3f3f3f3f
      7 struct node
      8 {
      9     int to;
     10     int nex;
     11     int cost;
     12 } edge[maxn<<2];
     13 int head[maxn<<2],num=0;
     14 int dis[maxn],ans[maxn],mx[maxn];
     15 int S,root;
     16 int Size[maxn],vis[maxn];
     17 int n,m,tot=0;
     18 void addedge(int fr,int to,int cost)
     19 {
     20     edge[num].to=to;
     21     edge[num].cost=cost;
     22     edge[num].nex=head[fr];
     23     head[fr]=num++;
     24 }
     25 void Find(int x,int rt)
     26 {
     27     Size[x]=1;
     28     mx[x]=0;
     29     for(int i=head[x]; i!=-1; i=edge[i].nex)
     30     {
     31         int to=edge[i].to;
     32         if(to==rt||vis[to])
     33             continue;
     34         Find(to,x);
     35         Size[x]+=Size[to];
     36         mx[x]=max(mx[x],Size[to]);
     37     }
     38     mx[x]=max(mx[x],S-Size[x]);
     39     if(mx[x]<mx[root])
     40         root=x;
     41 }
     42 int a[maxn];
     43 void get_dis(int x,int len,int rt)
     44 {
     45     dis[++tot]=a[x];
     46     for(int i=head[x]; i!=-1; i=edge[i].nex)
     47     {
     48         int to=edge[i].to;
     49         if(to==rt||vis[to])
     50             continue;
     51         a[to]=len+edge[i].cost;
     52         get_dis(to,len+edge[i].cost,x);
     53     }
     54 }
     55 void solve(int x,int len,int w)
     56 {
     57     tot=0;
     58     a[x]=len;
     59     get_dis(x,len,0);
     60     for(int i=1; i<=tot; i++)
     61     {
     62         for(int j=1; j<=tot; j++)
     63         {
     64             if(i==j)
     65                 continue;
     66             ans[dis[i]+dis[j]]+=w;
     67         }
     68     }
     69 }
     70 void divide(int x)
     71 {
     72     solve(x,0,1);
     73     vis[x]=1;
     74     for(int i=head[x]; i!=-1; i=edge[i].nex)
     75     {
     76         int to=edge[i].to;
     77         if(vis[to])
     78             continue;
     79         solve(to,edge[i].cost,-1);//去重
     80         S=Size[x],root=0,mx[0]=Size[x];
     81         Find(to,x);
     82         divide(root);
     83     }
     84 }
     85 int main()
     86 {
     87     memset(head,-1,sizeof(head));
     88     scanf("%d %d",&n,&m);
     89     int st,ed,cost;
     90     for(int i=1; i<n; i++)
     91     {
     92         scanf("%d %d %d",&st,&ed,&cost);
     93         addedge(st,ed,cost);
     94         addedge(ed,st,cost);
     95     }
     96     S=n,root=0,mx[0]=n;
     97     Find(1,0);
     98     divide(root);
     99     int tmp;
    100     for(int i=1; i<=m; i++)
    101     {
    102         scanf("%d",&tmp);
    103         printf("%s
    ",ans[tmp]?"AYE":"NAY");
    104     }
    105     return 0;
    106 }
  • 相关阅读:
    sql 拼写
    五、URL Routing介绍
    六、防止JavaScript注入攻击
    七、创建自定义的HTML Helper
    二、理解Models,Views,Controllers
    一、使用ASP.NET MVC创建应用程序
    自己写的临时表应用
    四、理解视图层,视图数据和HTML辅助
    三、理解控制器、控制器动作和ActionResults
    Extensions (扩展)方法
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10453456.html
Copyright © 2020-2023  润新知