P3565 tree dp

  This question is not OK because they feel thought out.

Let me talk about the violence of it, take the three points so that the distance between every two equally how to do it, appears to be very complicated way, but closer examination reveals the answer from a point between the son and the father or the son.

Violence enumerate three points and then calculate distance between two points, then two ST table can be done n ^ 3.

Consider a little bit of violence between the solution we have found the answer and the answer among the various sub-tree for each point between our statistics are answers and each sub-tree of its internal sub-tree and father.

Consider the enumeration of each point as the center and then use statistical answer specific sub-tree we found that this is actually the completion of the above process.

Complexity n ^ 2. By this problem. Very clever. Relatively problem-solving violence.

//#include<bits/stdc++.h>
#include<iomanip>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<deque>
#include<cmath>
#include<ctime>
#include<cstdlib>
#include<stack>
#include<algorithm>
#include<vector>
#include<cctype>
#include<utility>
#include<set>
#include<bitset>
#include<map>
#define INF 1000000000
#define ll long long
#define min(x,y) ((x)>(y)?(y):(x))
#define max(x,y) ((x)>(y)?(x):(y))
#define RI register ll
#define db double
#define EPS 1e-8
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
    return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
    int x=0,f=1;char ch=getc();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
    return x*f;
}
const int MAXN=5010;
int n,len,maxx;
int d[MAXN];
ll ans,f1[MAXN],f2[MAXN],f[MAXN];
int lin[MAXN],ver[MAXN<<1],nex[MAXN<<1];
inline void add(int x,int y)
{
    ver[++len]=y;
    nex[len]=lin[x];
    lin[x]=len;
}
inline void dfs(int x,int father)
{
    d[x]=d[father]+1;++f[d[x]];
    maxx=max(maxx,d[x]);
    for(int i=lin[x];i;i=nex[i])
    {
        int tn=ver[i];
        if(tn==father)continue;
        dfs(tn,x);
    }
}
int main()
{
    freopen("1.in","r",stdin);
    n=read();
    for(int i=1;i<n;++i)
    {
        int x,y;
        x=read();y=read();
        add(x,y);add(y,x);
    }
    for(int i=1;i<=n;++i)
    {
        memset(f1,0,sizeof(f1));
        memset(f2,0,sizeof(f2));
        for(int j=lin[i];j;j=nex[j])
        {
            int tn=ver[j];
            maxx=0;d[i]=0;
            dfs(tn,i);
            for(int k=1;k<=maxx;++k)
            {
                ans+=f2[k]*f[k];
                f2[k]+=f[k]*f1[k];
                f1[k]+=f[k];f[k]=0;
            }
        }
    }
    printf("%lld\n",ans);
    return 0;
}
View Code

Of course there are my original ideas about tree dp f [i] [j] expressed as i i distance from the root of j is the number of points of this great demand f [i] [j] = f [tn] [j -1]; f [x] [0] = 1;

Consider how the statistics of the answers in this place I encountered little difficulty obvious answer is from the inside of the sub-tree as to what we can recursively be solved between the tree and its sub-sub-tree and father.

How statistical answer is a heavy and difficult, here's a comparison of the state of the gods I do not think it necessarily want to count the answers, we must first get the number from the number of i j is the point of a single point and then to calculate.

Provided g [i] [j] indicates the point directly to the LCA distance d is to the point i is the number of distance dj of about looks very natural, but also because it can compare our f [i] [j] combined together to form an answer.

//#include<bits/stdc++.h>
#include<iomanip>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<deque>
#include<cmath>
#include<ctime>
#include<cstdlib>
#include<stack>
#include<algorithm>
#include<vector>
#include<cctype>
#include<utility>
#include<set>
#include<bitset>
#include<map>
#define INF 1000000000
#define ll long long
#define min(x,y) ((x)>(y)?(y):(x))
#define max(x,y) ((x)>(y)?(x):(y))
#define RI register ll
#define db double
#define EPS 1e-8
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
    return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
    int x=0,f=1;char ch=getc();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
    return x*f;
} 
Const  X,int= MAXN 5010 ;
 int n-, len, Maxx;
 int D [MAXN]; 
LL ANS; 
int F [MAXN] [MAXN]; // F [i] [j] denotes the distance from the point i of the j th point clearly the number of F [I] [J] + = F [TN] [-J. 1]; 
int ; G [MAXN] [MAXN] // when g [i] [j] represents a point a distance d from the LCA the distance from point i to point to the number of dj
 // first described herein subtree internal necessity for this state to answer the matter processed recursively
 // answer using the G [i] between the own subtree subtree [j] * f [i] [j] to calculate
 // so it is clear that sub-tree and father g [i] [0] is the answer discussion between father
 // sum up the answer to solving the statistical proof. 
int LIN [MAXN], Ver [MAXN << . 1 ], NEX [MAXN << . 1 ]; 
inline void the Add ( int int Y) 
{
    ver[++len]=y;
    nex[len]=lin[x];
    lin[x]=len;
}
int main()
{
    freopen("1.in","r",stdin);
    n=read();
    for(int i=1;i<n;++i)
    {
        int x,y;
        x=read();y=read();
        add(x,y);add(y,x);
    }
    return 0;
}
View Code

 

 

 

Guess you like

Origin www.cnblogs.com/chdy/p/11300692.html