[POI2014]HOT-Hotels

Posted si-rui-yang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[POI2014]HOT-Hotels相关的知识,希望对你有一定的参考价值。

题目

因为三个点肯定会有一个中转点,然后从中将一棵无根树转成有根数,然后再通过乘法原理(c2表示两两的乘积,若有第三个数就可以变成3数相乘,就可以乘法原理了)

为什么要搜索每颗子树而不从从自己的根开始搜了

以为这样就有可能不是中转点了

所以这样的话时间复杂的为O(N^2),但是可以使用长链剖分优化为O(N),虽然我不知道怎么用,没有学过

技术分享图片
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
inline long long read()
{
    long long f=1,ans=0;char c;
    while(c<0||c>9){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){ans=ans*10+c-0;c=getchar();}
    return f*ans;
}
long long c1[10001],c2[10001],n;
struct node{
    long long u,v,nex;
}x[10001];
long long cnt=0;
long long ans[10001],head[5001],maxn,sum;
void add(long long u,long long v)
{
    x[cnt].u=u,x[cnt].v=v,x[cnt].nex=head[u],head[u]=cnt++;
}
void dfs(long long pos,long long fath,long long anss)
{
    maxn=max(maxn,anss);
    ans[anss]++;
    for(long long i=head[pos];i!=-1;i=x[i].nex)
    {
        if(x[i].v!=fath) dfs(x[i].v,pos,anss+1);
    }
}
int main()
{
    memset(head,-1,sizeof(head));
     n=read();
     for(long long i=1;i<n;i++) 
     {
         long long u=read(),v=read();
         add(u,v),add(v,u);
//         cout<<i<<endl;
     }
     
     for(long long i=1;i<=n;i++)
     {
         memset(c1,0,sizeof(c1));
         memset(c2,0,sizeof(c2));
         for(long long j=head[i];j!=-1;j=x[j].nex)
         {
             maxn=0;
             dfs(x[j].v,i,1);
             for(long long k=1;k<=maxn;k++)
             {
                 sum+=ans[k]*c2[k];
                 c2[k]+=c1[k]*ans[k];
                 c1[k]+=ans[k];
                 ans[k]=0;
             }
        }
     }
     cout<<sum;
}
View Code

 

以上是关于[POI2014]HOT-Hotels的主要内容,如果未能解决你的问题,请参考以下文章

[POI2014]HOT-Hotels

POI题目乱选

[POI 2014] Little Bird

缺少 SQL SERVER 2014 代码片段

[bzoj3872][Poi2014]Ant colony_树形dp

bzoj3524:[Poi2014]Couriers