# 2416. Lit flame (flame)

Title Description
bx2k invented a lot of interesting items. Ben because he is a god. He decided to use an ancient method of timing: burning rope.

bx2k There are many varying lengths of uniform thickness of the rope, if it's an ignited, will burn to a per unit length along the direction of the rope.

The n-bx2k $ $ rope arranged in a tree ($ edges of undirected FIG n-$ $ points $ 1 n-) shape. Which represents the rope side. Only two contacts at the ends of the rope. If one end of a rope begins to burn, the rope in contact with it will also be lit.

bx2k only at the beginning of a number of simultaneously lit tree leaf nodes. Now he wants to know he can count how many different times. Statistics can be a time-if and only if there is a way to ignite the leaves makes from the beginning to ignite the whole tree is just burned out of time for that time.

Since many possible answers, you result output program number of $ 998244353 $ ($ = 7 × 17 × 223 + 1 $, a prime number) modulo. Front and $ 1000 $ small output can be time statistics.
Data range
to 100% of the data, $ 2 \ le n \ le 500,1 \ le w \ le 10000 $
explanations
will be converted into a rooted tree root

Consider violence, since only the leaf nodes burned, so the $ 2 ^ n $ enumeration began to burn the leaves of a state, and then consider how to quickly answer statistics

Each point can be converted to when to begin burned, denoted by $ f $ value, initially only to burn the leaves is $ 0 $, and the rest is $ inf $, then so would be $ dfs $ twice, the first pass is updated up from the bottom up is the second time from the update, the process can be $ F $, and each edge $ (x, y) $ answer is $ \ frac {f_x + f_y + w} { 2} $, where there may not burned this edge, but does not affect the

Then consider positive solutions, we found that the situation can be divided into two burned, either between the two farthest burned leaves, or a burnt leaf, a leaf is not burned farthest, so we can enumerate two leaf nodes, then our aim is to try to make this program be the answer, so we will be able to burn all burned leaf node, then the above method to determine whether this program is the answer to

Specifically determination can be burned leaf node, leaf nodes are assumed two $ a, b $

1. $ a, b $ and burn:
Consider a leaf node $ c $, if the $ dis (a, b) \ le dis (b, c) $ or $ dis (a, b) \ le dis (a, c) $, $ c $ point can be burned, you can understand how the drawing

2. $ a $ $ b $ does not burn burn:
Consider a leaf node $ c $, then if $ dis (a, b) \ le dis (b, c) $, $ c $ point can be burned, can draw understand what

Efficiency: $ O (n ^ 3 + n ^ 2logn) $
Code

#include <bits/stdc++.h>
using namespace std;
const int N=505,M=N<<1;
int n,hd[N],V[M],nx[M],t,in[N],W[M],h[N],H,rt;
int s[N],d[N][N],fa[N],dp[N],A[N*N],S,q[N],Q;
void add(int u,int v,int w){
    nx[++t]=hd[u];in[v]++;V[hd[u]=t]=v;W[t]=w;
}
void dfs(int u,int fr){
    fa[u]=fr;dp[u]=dp[fr]+1;
    for (int i=hd[u];i;i=nx[i])
        if (V[i]!=fr) s[V[i]]=s[u]+W[i],dfs(V[i],u);
}
int Dfs(int u){
    for (int i=hd[u];i;i=nx[i]) if (V[i]!=fa[u])
        Dfs(V[i]),s[u]=min(s[u],s[V[i]]+W[i]);
    return s[u];
}
int work(){
    for (int i=1;i<=n;i++) s[i]=1e9;
    for (int i=1;i<=Q;i++) s[q[i]]=0,q[i]=0;
    s[rt]=Dfs(rt);int ss=0,l=1,r=1;q[1]=rt;
    while(l<=r){
        int x=q[l++];
        for (int i=hd[x];i;i=nx[i])
            if (V[i]!=fa[x]){
                s [V [i]] = min (p [V [i]], s [x] + W [i]);
                ss=max(s[x]+s[V[i]]+W[i],ss);
                q[++r]=V[i];
            }
    }
    return ss;
}
bool J(int a,int b){
    q[1]=a;q[Q=2]=b;
    for (int i=1;i<=H;i++)
        if (h[i]!=a && h[i]!=b)
            if (d[a][b]<=d[b][h[i]]||d[a][b]<=d[a][h[i]]) q[++Q]=h[i];
    return work()==d[a][b];
}
bool G(int a,int b){
    q[Q=1]=a;
    for (int i=1;i<=H;i++)
        if (h[i]!=a && h[i]!=b)
            if (d[a][b]<=d[b][h[i]]) q[++Q]=h[i];
    return work()==(d[a][b]<<1);
}
int main () {
    scanf("%d",&n);
    for (int u,v,w,i=1;i<n;i++)
        scanf("%d%d%d",&u,&v,&w),
        add(u,v,w),add(v,u,w);
    for (int i=1;i<=n;i++)
        if (in[i]<2) h[++H]=i;
        else rt=i;dfs(rt,0);
    for (int x,y,i=1;i<=n;i++)
        for (int j=i;j<=n;j++){
            x=i,y=j;if (dp[x]<dp[y]) swap(x,y);
            while(dp[x]>dp[y]) x=fa[x];
            while(x!=y) x=fa[x],y=fa[y];
            d[i][j]=d[j][i]=s[i]-s[x]+s[j]-s[x];
        }
    for (int i=1;i<=H;i++)
        for (int j=1;j<=H;j++){
            if (i<j && J(h[i],h[j])) A[++S]=d[h[i]][h[j]];
            if (i!=j && G(h[i],h[j])) A[++S]=(d[h[i]][h[j]]<<1);
        }
    sort(A+1,A+S+1);S=unique(A+1,A+S+1)-A-1;
    printf("%d\n",S);S=min(S,1000);
    for (int i=1;i<=S;i++){
        printf("%d",A[i]>>1);
        if (A[i]&1) putchar('.'),putchar('5');
        putchar(i<S?' ':'\n');
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/xjqxjq/p/11305281.html