zoukankan      html  css  js  c++  java
  • hdu4607树的直径,spfa

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607

    题意:前一阵子做的,题意忘记了,大体就是求树的直径,就是树的最长路的长度。

    思路:树的直径有这么一个算法,从树上任意一点出发,找一条最长路,终点为A,再从A点出来,找一条最长路,终点为B,那么树的直径就是AB的长度。求最长路可用dfs或者spfa来写。

    #include<iostream>
    #include<vector>
    #include<queue>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    
    const int maxn=100000+5;
    const int INF=0x3f3f3f3f;//不能随便写,不然后面的memset出错
    int n,m;
    vector<int> list[maxn];
    queue<int> q;
    int dis[maxn];
    int inq[maxn];
    
    void spfa(int p)
    {
        int u;
        memset(dis,0x3f,sizeof(dis));
        memset(inq,0,sizeof(inq));
    //for(int i=0;i<=n;i++)
    //{
    //    dis[i]=INF;
    //    inq[i]=0;
    //}
        dis[p]=0;inq[p]++;
        q.push(p);
        while(!q.empty())
        {
            u=q.front();
            q.pop();inq[u]--;//因为某个点可能重复入队,所以出队的时候也要标记,和bfs不同,bfs只用入队标记,因为只入队一次
            for(int i=0;i<list[u].size();i++)
                if(dis[u]+1<dis[list[u][i]])
                {
                    dis[list[u][i]]=dis[u]+1;
                    if(inq[list[u][i]]==0)
                    {
                        q.push(list[u][i]);
                        inq[list[u][i]]++;
                    }
                }
        }
    }
    int main()
    {
        int t,u,v,k;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++)
                list[i].clear();
            for(int i=1;i<n;i++)
            {
                scanf("%d%d",&u,&v);
                list[u].push_back(v);
                list[v].push_back(u);
            }
            int p=1;
            spfa(p);
            for(int i=2;i<=n;i++)
                if(dis[i]>dis[p])
                   p=i;
            spfa(p);
            for(int i=2;i<=n;i++)
                if(dis[i]>dis[p])
                   p=i;
            p=dis[p];//
            while(m--)
            {
                scanf("%d",&k);
                if(k<=p+1) printf("%d
    ",k-1);
                else printf("%d
    ",(k-p-1)*2+p);
            }
    
        }
        return 0;
    }
  • 相关阅读:
    监控里的主码流和子码流是什么意思
    监控硬盘容量计算
    一个能让你了解所有函数调用顺序的Android库
    电工选线
    oracle linux dtrace
    list all of the Oracle 12c hidden undocumented parameters
    Oracle Extended Tracing
    window 驱动开发
    win7 x64 dtrace
    How to Use Dtrace Tracing Ruby Executing
  • 原文地址:https://www.cnblogs.com/54zyq/p/3271310.html
Copyright © 2011-2022 走看看