HDU 4514 【非联通无向图判环,树直径】

题目很明显是判环+树直径。

然后自己有这么几个坑点。

第一是没有搞清楚哪一种方法拿来判环合适。第二是没想到图可能是不连通的,需要循环寻找每棵树进行直径的寻找。第三是在找直径上的dfs上有错。。。

恩,然后就是手动扩栈了一下。

#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <stack>
#include <string.h>
using namespace std;
#define maxn 1000100
#define maxm 100010
struct node
{
    int v,val,next;
}que[maxn<<1];
int head[maxm];
int top,ans,n,m,st,cnt;
int vis[maxm],dp[maxm],a[maxm],father[maxm];
void add(int x,int y,int z)
{
    que[top].v=x;que[top].val=z;que[top].next=head[y];head[y]=top++;
    que[top].v=y;que[top].val=z;que[top].next=head[x];head[x]=top++;
}
int min(int x,int y){return x<y?x:y;}
int max(int x,int y){return x>y?x:y;}

/*void dfs(int u)
{
    vis[u]=1;
    int j,v;
    for(j=head[u];j!=-1;j=que[j].next)
    {
        v=que[j].v;
        if(vis[v]) continue;
        dfs(v);
        dp[u]=max(dp[u],dp[v]+que[j].val);
        ans=max(dp[u],ans);
        break;
    }
    if(j==-1) return;
    for(j=que[j].next;j!=-1;j=que[j].next)
    {
        v=que[j].v;
        if(vis[v]) continue;
        dfs(v);
        dp[u]=max(dp[u],dp[v]+que[j].val);
        ans=max(ans,dp[u]);
    }
}*/
int dfs(int k,int deep,int len)
{
    vis[k]=1;
    if(ans<deep)ans=deep;
    if(head[k]==-1) return 0;
    int j,v,temp,maxr=0;
    int dis[2],cnt=0;
    for(j=head[k];j!=-1;j=que[j].next)
    {
        v=que[j].v;
        if(vis[v]) continue;
        temp=dfs(v,deep+que[j].val,que[j].val);
        if(maxr<temp)    maxr=temp;
        if(cnt<2)    dis[cnt++]=temp;
        else
        {
            int f;
            if(dis[0]<dis[1])    f=0;
            else                f=1;
            if(dis[f]<temp)      dis[f]=temp;
        }
    }
    if(cnt>=2 && ans<dis[0]+dis[1])   ans=dis[0]+dis[1];
    return maxr+len;
}
int find(int x)
{
    int i=x;
    while(i!=father[i])
        i=father[i];
    int j=x,tmp;
    while(j!=i)
    {
        tmp=father[j];
        father[j]=i;
        j=tmp;
    }
    return i;
}
void join(int x,int y)
{
    father[x]=y;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        st=top=ans=cnt=st=0;
        
        for(int i=0;i<=n;i++) head[i]=-1,dp[i]=0,father[i]=i,vis[i]=0;
        int x,y,z;
        int flag=0;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            if(x!=y)
            {int xx=find(x),yy=find(y);
            if(xx==yy) flag=1;
                else join(xx,yy);}
        }
        top=0;
        if(flag) {printf("YES\n");continue;}
        for(int i=1;i<=n;i++) if(!vis[i]) dfs(i,0,0);
        printf("%d\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值