2019 National Day off cattle camp day1 2019 points divide and conquer

Topic link: https: //ac.nowcoder.com/acm/contest/1099/I

Partition point, calculating the number of paths when the first distance from each point to the root module 2019, can be calculated when the O (n) determined number, for special handling after molding 2019 to 0.

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 100005
#define inf 0x3f3f3f3f
int n,k,cnt,root,ans,maxx,head[maxn],size[maxn],son[maxn],vis[maxn],num[maxn];
struct edge{
    int to,next,val;
}e[maxn];
vector<int>dis;
void add(int u,int v,int val)
{
    e[++cnt].to=v;
    e[cnt].next=head[u];
    e[cnt].val=val;
    head[u]=cnt;
}
void dfs_size(int u,int fa)//求各点子树大小 
{
    size[u]=1;son[u]=0;
    for(int i=head[u];i;i=e[i].next)
    {
        int v=e[i].to;
        if(v!=fa&&!vis[v])
        {
            dfs_size(v,u);
            size[u]+=size[v];
            son[u]=max(son[u],size[v]);
        }
    }
}
void dfs_root(int N,int u,int fa)//求重心 
{
    son[u]=max(son[u],N-size[u]);
    if(maxx>son[u])
    {
        root=u;
        maxx=son[u];
    }
    for(int i=head[u];i;i=e[i].next)
    {
        int v=e[i].to;
        if(v!=fa&&!vis[v])
        dfs_root(N,v,u);
    }
}
void dfs_dis(int U,intFA, int Val) // Determine all points to the root of the distance 
{ 
    Val % = 2019 ; 
    NUM [Val] ++ ;
     // dis.push_back (Val); 
    for ( int I = head [U]; I; I = E [I] .next) 
    { 
        int V = E [I] .to;
         IF ! (V FA = &&! VIS [V]) 
        dfs_dis (V, U, Val + E [I] .val); 
    } 
} 
int CAL ( int U, int Val) // calculate k less number of paths 
{
     for ( int I = 0;i<=2019;i++)
    num[i]=0;
    //dis.clear();
    dfs_dis(u,0,val);
    //sort(dis.begin(),dis.end());
    int l=0,r=dis.size()-1,ret=0;
    for(int i=1;i<2019;i++)//two-pointer
    {
        if(num[i]&&num[2019-i])ret+=num[i]*num[2019-i];
    }
    ret/=2;
    RET + = NUM [ 0 ] * (NUM [ 0 ] - . 1 ) / 2 ;
     return RET; 
} 
void DFS ( int U) 
{ 
    dfs_size (U, 0 ); 
    Maxx = INF; 
    dfs_root (size [U], U, 0 ); 
    ANS + = CAL (the root, 0 ); // this case paths is calculated without including the number of paths through the roots, the latter need to subtract this number of paths 
    VIS [the root] = . 1 ; // will roo selected and traversed t marked, which prevents process after the partition 
    for ( int I = head [the root]; I; I = E [I] .next) 
    {
        intE = V [I] .to, Val = E [I] .val;
         IF (! VIS [V]) 
        { 
            ANS - CAL = (V, Val); // subtree plus all sides dis (u, v ) after the number of paths satisfying the number of paths is subtracted 
            DFS (V); // recursive partition 
        } 
    } 
} 
int main () 
{ 
    the while (Scanf ( " % D " !, & n-) = the EOF) 
    { 
        int U, V, Val;
         for ( int I = . 1 ; I <= n-; I ++ ) 
        head [I] = VIS [I] = 0 ; 
        CNT = ANS = 0;
        for(int i=1;i<n;i++)
        {
            scanf("%d%d%d",&u,&v,&val);
            add(u,v,val);
            add(v,u,val);
        }
        dfs(1);
        printf("%d\n",ans);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/chen99/p/11617356.html