1. 程式人生 > >[bzoj3872][Poi2014]Ant colony_樹形dp

[bzoj3872][Poi2014]Ant colony_樹形dp

name 有意 lld www. urn href ring har bzoj3

Ant colony bzoj-3872 Poi-2014

題目大意:說不明白.....題目鏈接

註釋:略。


想法:兩個思路都行。

反正我們就是要求出每個葉子節點到根節點的每個路徑權值積。

可以將邊做為代理根。或者將邊斷掉。

最後,附上醜陋的代碼... ...

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=1000010;
const ll inf=1<<30;
int n,m,cnt,r1,r2;
ll K,ans;
int to[maxn<<1],next[maxn<<1],head[maxn],d[maxn],fa[maxn];
ll l[maxn],r[maxn],v[maxn];
inline void add(int a,int b)
{
    to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
inline int rd()
{
    int ret=0,f=1;  char gc=getchar();
    while(gc<‘0‘||gc>‘9‘) {if(gc==‘-‘)    f=-f;   gc=getchar();}
    while(gc>=‘0‘&&gc<=‘9‘)   ret=ret*10+gc-‘0‘,gc=getchar();
    return ret*f;
}
void dfs(int x)
{
    for(int i=head[x];i!=-1;i=next[i])  if(to[i]!=fa[x])
    {
        fa[to[i]]=x;
        if(d[to[i]]==1) l[to[i]]=l[x],r[to[i]]=r[x];
        else    l[to[i]]=min(inf,l[x]*(d[to[i]]-1)),r[to[i]]=min(inf,(r[x]+1)*(d[to[i]]-1)-1);
        dfs(to[i]);
    }
}
int main()
{
    n=rd(),m=rd(),K=rd();
    int i,a,b;
    for(i=1;i<=m;i++)    v[i]=rd();
    v[m+1]=inf+1;
    sort(v+1,v+m+1);
    r1=rd(),r2=rd(),d[r1]++,d[r2]++;
    memset(head,-1,sizeof(head));
    for(i=1;i<n-1;i++)   a=rd(),b=rd(),add(a,b),add(b,a),d[a]++,d[b]++;
    if(d[r1]==1)    l[r1]=r[r1]=K;
    else    l[r1]=K*(d[r1]-1),r[r1]=(K+1)*(d[r1]-1)-1;
    if(d[r2]==1)    l[r2]=r[r2]=K;
    else    l[r2]=K*(d[r2]-1),r[r2]=(K+1)*(d[r2]-1)-1;
    dfs(r1),dfs(r2);
    for(i=1;i<=n;i++)    if(d[i]==1)
        a=lower_bound(v+1,v+m+1,l[i])-v,b=upper_bound(v+1,v+m+1,r[i])-v,ans+=(b-a)*K;
    printf("%lld",ans);
    return 0;
}

小結:有意思.../xyx

[bzoj3872][Poi2014]Ant colony_樹形dp