zoukankan      html  css  js  c++  java
  • [LOJ 6159] 最长树链

    看到要求gcd不为1所以肯定在这条答案链上都是一个质数的倍数,所以就会产生一个很暴力的想法

    没错,正解就是这样的暴力

    只让走是i(素数)倍数的点,作最长链

    最长链可以树形dp或两遍bfs,一遍找端点,一遍过长度即可

    复杂度:未证

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<vector> 
    #include<cmath>
    using namespace std;
    inline int read()
    {
        int 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;
    }
    map<int,int> ma;
    struct node{
        int u,v,nex;
    }x[200001];
    int cnt,n,head[100001];
    void add(int u,int v)
    {
        x[cnt].u=u,x[cnt].v=v,x[cnt].nex=head[u],head[u]=cnt++;
    }
    int v[100001],sry,have[100001];
    int vis[100001];
    int dis[100001];
    vector<int> ve[100005];
    int vis1[100001];
    int maxn;
    int bfs(int u)
    {
        queue<int> que;
        int ans=u;
        que.push(u);
        vis[u]=1,dis[u]=1;
        while(!que.empty())
        {
            int xx=que.front();que.pop();
            for(int i=head[xx];i!=-1;i=x[i].nex)
            {
                if(have[x[i].v]==0) continue;
                if(vis[x[i].v]) continue;
                vis[x[i].v]=1;
                dis[x[i].v]=dis[xx]+1;
                if(dis[x[i].v]>dis[ans]) ans=x[i].v;
                que.push(x[i].v);
            }
        }
        while(!que.empty()) que.pop();
        que.push(ans),vis1[ans]=1,dis[ans]=1;
        while(!que.empty())
        {
            int xx=que.front();que.pop();
            for(int i=head[xx];i!=-1;i=x[i].nex)
            {
                if(have[x[i].v]==0) continue;
                if(vis1[x[i].v]) continue;
                dis[x[i].v]=dis[xx]+1;
                vis1[x[i].v]=1;
                if(dis[x[i].v]>dis[ans]) ans=x[i].v;
                que.push(x[i].v);
            }
        }
        return dis[ans];
    }
    int main()
    {
        memset(head,-1,sizeof(head));
        n=read();
        for(int i=1;i<n;i++)
        {
            int u=read(),v=read();
            add(u,v),add(v,u);
        }
        for(int i=1;i<=n;i++) v[i]=read();
        for(int i=1;i<=n;i++) 
        {
            int x=v[i];
            for(int j=2;j<=sqrt(x);j++) 
            {
                if(x%j!=0) continue;
                if(ma[j]==0) ma[j]=++sry;
                ve[ma[j]].push_back(i);
                while(x%j==0) x/=j;
            }
            if(x!=1) 
            {
                if(ma[x]==0) ma[x]=++sry;
                ve[ma[x]].push_back(i);
            }
        }
        for(int i=1;i<=sry;i++)
        {
            int size=ve[i].size();
            for(int j=0;j<size;j++) have[ve[i][j]]=1,vis[ve[i][j]]=0,vis1[ve[i][j]]=0;
            for(int j=0;j<size;j++) 
            {
                if(vis[ve[i][j]]==1) continue;
                maxn=max(maxn,bfs(ve[i][j]));
            }
            for(int j=0;j<size;j++) have[ve[i][j]]=0,vis[ve[i][j]]=1,vis1[ve[i][j]]=1;
        }
        cout<<maxn;
    }
    View Code
  • 相关阅读:
    结果填空:青蛙爬井
    天上的星星 (前缀和)
    Poj3253 Fence Repair (优先队列)
    Requests+BeautifulSoup+正则表达式爬取猫眼电影Top100(名称,演员,评分,封面,上映时间,简介)
    数字图像处理之几种滤波器
    CodeForces
    直方图部分
    Codeforces Round #431 (Div. 2)
    2017中国大学生程序设计竞赛
    C++中数字与字符串之间的转换(转载自http://www.cnblogs.com/luxiaoxun/)
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/9703469.html
Copyright © 2011-2022 走看看