【haoi2009】毛毛虫

版权声明:蒟蒻的原创,转载请注明出处,附上链接。 https://blog.csdn.net/qq_39670434/article/details/82252691

题面

题目描述
对于一棵树,我们可以将某条链和与该链相连的边抽出来,看上去就象成一个毛毛虫,点数越多,毛毛虫就越大。例如下图左边的树,抽出一部分就变成了右边的一个毛毛虫了。
这里写图片描述
输入格式
第一行两个整数N,M,分别表示树中结点个数和树的边数。
接下来M行,每行两个整数a, b表示点a和点 b有边连接(a, b≤N)。你可以假定没有一对相同的(a, b)会出现一次以上。
输出格式
一个整数, 表示最大的毛毛虫的大小。

题解

有很多同学都用了树归….然而我并没有用那个…
我求直径的方法是两遍spfa(小数据用dfs)。这道题目是一样的啊。,,然后我给每一个点的权值赋为这个点的度数,然后求直径就行了。

唯一的注意点就是,两个点相连的时候有度数的减损,要处理好这个减损值。

code

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    int num=0;char c=' ';bool flag=true;
    for(;c>'9'||c<'0';c=getchar())
        if(c=='-')
            flag=false;
    for(;c>='0'&&c<='9';num=(num<<3)+(num<<1)+c-48,c=getchar());
    return flag ? num : -num;
}
namespace graph{
    const int maxn=300020;
    struct node{
        int y,next;
    }a[maxn<<1];
    int head[maxn],top=0;
    void insert(int x,int y){
        a[top].y=y;
        a[top].next=head[x];
        head[x]=top++;
    }
    int n,m,val[maxn];
    void init(){
        memset(head,-1,sizeof head);
        n=read();m=read();
        for(int i=1;i<=m;i++){
            int x=read();
            int y=read();
            insert(x,y);
            insert(y,x);
            val[x]++;
            val[y]++;
        }
    }
}using namespace graph;
namespace shortest{
    int dis[maxn];
    bool vis[maxn];
    void spfa(int s){
        memset(dis,10,sizeof dis);
        memset(vis,0,sizeof vis);
        queue<int>q;
        vis[s]=true;
        dis[s]=val[s];
        q.push(s);
        while(q.size()){
            int x=q.front();
            vis[x]=false;
            q.pop();
            for(int i=head[x];i+1;i=a[i].next){
                int y=a[i].y;
                if(dis[y]>dis[x]+val[y]){
                    dis[y]=dis[x]+val[y]-1;
                    if(!vis[y]){
                        vis[y]=true;
                        q.push(y);
                    }
                }
            }
        }
    }
}using namespace shortest;
int main(){
    freopen("WORM.in","r",stdin);
    freopen("WORM.out","w",stdout);
    //某oj交题目还用文件输入输出
    init();
    spfa(1);
    int now=1;
    for(int i=1;i<=n;i++)
        if(dis[now]<dis[i])
            now=i;
    spfa(now);
    int en=now;
    for(int i=1;i<=n;i++)
        if(dis[en]<dis[i])
            en=i;
    printf("%d\n",dis[en]+1);
    fclose(stdin);
    fclose(stdout);
    return 0;
}
阅读更多
换一批

五只毛毛虫(转)

11-21

第一只毛毛虫 rnrn  话说第一只毛毛虫,有一天爬呀爬呀过山河,终于来到这棵苹果树下。他并不知道这是一棵苹果树,也不知树上长满了红红的苹果。当他看到同伴们往上爬时,不知所以 的就跟着往上爬。没有目的,不知终点,更不知生为何求、死为何所。他的最后结局 呢?也许找到了一颗大苹果,幸福的过了一生;也可能在树叶中迷了路,颠沛流离糊 涂一生。不过可以确定的是,大部分的虫都是这样活着的,也不去烦恼什么是生命意义,倒也轻松许多。 rnrn  ************************************************************ rnrn  第二只毛毛虫 rnrn  有一天,第二只毛毛虫也爬到了苹果树下。他知道这是一棵苹果树,也确定他的「虫 生目标」就是找到一棵大苹果。问题是....他并不知道大苹果会长在什么地方?但他 猜想:大苹果应该长在大枝叶上吧!于是他就慢慢地往上爬,遇到分支的时候,就选 择较粗的树枝继续爬。 当然在这个毛虫社会中,也存在考试制度,如果有许多虫同时选择同一个分支,可是 要举行考试来决定谁才有资格通过大树枝。幸运的,这只毛毛虫一路过关斩将,每次 都能第一志愿的选上最好的树枝,最后他从一枝名为「大学」的树枝上,找到了一颗 大苹果。不过他发现这颗大苹果并不是全树上最大的,顶多只能称是局部最大。因为 在它的上面还有一颗更大的苹果,号称「老板」,是由另一只毛毛虫爬过一个名为 「创业」的树枝才找到的。令他泄气的是,这个创业分支是他当年不屑于爬的一棵细 小的树枝 rnrn  ************************************************************ rnrn  第三只毛毛虫 rnrn  接着,第三只毛毛虫也来到了树下。这只毛毛虫相当难得,小小年纪,却自己研制了 一副望远镜。在还未开始爬时,就先利用望远镜搜寻一番,找到了一棵超大苹果。同 时,他发觉当从下往上找路时,会遇到很多分支,有各种不同的爬法;但若从上往下 找路时,却只有一种爬法。他很细心的从苹果的位置,由上往下反推至目前所处的位 置,记下这条确定的路径。于是,他开始往上爬了,当遇到分支时,他一点也不慌 张,因为他知道该往那条路走不必跟着一大堆虫去挤破头。譬如说,如果他的目标是 一颗名叫「教授」的苹果,那应该爬「升学」这条路;如果目标是「老板」,那应该 爬「创业」这分支;若目标是「政客」,也许早就该爬「厚黑之道」这条路了。 最后,这只毛毛虫「应该」会有一个很好的结局,因为他己具备了「先觉」的条件 了。但也许会有一些意外的结局出现,因为毛毛虫的爬行相当缓慢,从预定苹果到抵 达时,需要一段时间。当他抵达时,也许苹果已被别的虫捷足先登,也许苹果已熟透 而烂掉了....。 rnrnrn  ************************************************************ rnrn  第四只毛毛虫 rnrn  第四只毛毛虫可不是一只普通的虫,同时具有先知先觉的能力。他不仅先觉知道自己 要何种苹果,更先知──知道未来苹果将如何成长。 因此当他带着那「先觉」的望眼镱时,他的目标并不是一颗大苹果,而是一芽含苞待 放的苹果花。他计算着自己的时程,并估计当他抵达时,这朵花正好长成一颗成熟的 大苹果,而且他将是第一个钻入大快朵颐的虫。果不其然,他获得所应得的,从此过 着幸福快乐的日子。 rnrn  ************************************************************ rnrn  第五只毛毛虫 rnrn  毛毛虫的故事本来应该到此结束了。因为所有故事的结局都必须是正面的且富有教育 意义。但仍有不少读者好奇:第五只毛毛虫到底怎么了....? 其实他什么也没做,就在树下躺着纳凉,而一颗颗大苹果就从天而降在他的身边。因为树上某一大片树枝早就被他的家族占领了。他的爷爷、爸爸、哥哥们盘据在某一树 干上,禁止他虫进入。然后苹果成熟时,就一颗颗的丢给底下的子孙们捡食。奉劝诸位,如果你不是含着金汤匙出生的,可不要妄想检到大苹果,因为反而会被砸死的。rn

没有更多推荐了,返回首页