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;
    }
  • 相关阅读:
    [HDU 3038] How Many Answers Are Wrong
    [BZOJ 4977][Lydsy1708月赛]跳伞求生
    [BZOJ4974] 字符串大师
    总结-exCRT
    [luogu 4777] exCRT
    [AHOI 2009] 中国象棋
    JavaScript MVC框架PK:Angular、Backbone、CanJS与Ember
    十一黄金周 加班加点随笔
    从两个设计模式到前端MVC-洪宇
    Todo&Rocket
  • 原文地址:https://www.cnblogs.com/54zyq/p/3271310.html
Copyright © 2011-2022 走看看