2 条题解

  • 0
    @ 2025-10-8 17:02:19
    #include<bits/stdc++.h>
    using namespace std;
    const int N=5e4+10;
    vector<int>G[N];
    int tsp,dfn[N],low[N],fa[N];
    int ans,d[N],td[N*2],q[N];
    void solve(int x,int y)
    {
        int cnt=0;for(int z=y;z!=fa[x];z=fa[z]) td[++cnt]=d[z];
        for(int i=1;i<=cnt;i++) td[i+cnt]=td[i];
        int l=1,r=1;q[1]=1;
        for(int i=2;i<=cnt*2;i++)
        {
            while(l<=r&&i-q[l]>cnt/2) l++;
            ans=max(ans,td[i]+td[q[l]]+i-q[l]);
            while(l<=r&&td[i]-i>=td[q[r]]-q[r]) r--;
            q[++r]=i;
        }
        for(int i=1;i<=cnt;i++) d[x]=max(d[x],td[i]+min(i,cnt-i));
    }
    void tarjan(int x,int xfa)
    {
        dfn[x]=low[x]=++tsp;
        for(int y:G[x])if(y!=xfa)
        {
            if(!dfn[y])
            {
                fa[y]=x;
                tarjan(y,x);
                low[x]=min(low[x],low[y]);
            }
            else low[x]=min(low[x],dfn[y]);
            if(dfn[x]<low[y])
            {
                ans=max(ans,d[x]+d[y]+1);
                d[x]=max(d[x],d[y]+1);
            }
        }
        for(int y:G[x])if(fa[y]!=x)
        {
            if(dfn[x]<dfn[y]) solve(x,y);
        }
    }
    int main()
    {
        int n,m;scanf("%d%d",&n,&m);
        while(m--)
        {
            int k,x,y;scanf("%d%d",&k,&x);k--;
            while(k--)
            {
                scanf("%d",&y);
                G[x].push_back(y);G[y].push_back(x);
                x=y;
            }
        }
        tsp=0;memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));
    	ans=0;tarjan(1,0);
        printf("%d\n",ans);
        return 0;
    }
    
    • 0
      @ 2025-10-8 17:02:05
      #include<bits/stdc++.h>
      using namespace std;
      const int N=5e4+10;
      vector<int>G[N];
      int tsp,dfn[N],low[N],fa[N];
      int ans,d[N],td[N*2],q[N];
      void solve(int x,int y)
      {
          int cnt=0;for(int z=y;z!=fa[x];z=fa[z]) td[++cnt]=d[z];
          for(int i=1;i<=cnt;i++) td[i+cnt]=td[i];
          int l=1,r=1;q[1]=1;
          for(int i=2;i<=cnt*2;i++)
          {
              while(l<=r&&i-q[l]>cnt/2) l++;
              ans=max(ans,td[i]+td[q[l]]+i-q[l]);
              while(l<=r&&td[i]-i>=td[q[r]]-q[r]) r--;
              q[++r]=i;
          }
          for(int i=1;i<=cnt;i++) d[x]=max(d[x],td[i]+min(i,cnt-i));
      }
      void tarjan(int x,int xfa)
      {
          dfn[x]=low[x]=++tsp;
          for(int y:G[x])if(y!=xfa)
          {
              if(!dfn[y])
              {
                  fa[y]=x;
                  tarjan(y,x);
                  low[x]=min(low[x],low[y]);
              }
              else low[x]=min(low[x],dfn[y]);
              if(dfn[x]<low[y])
              {
                  ans=max(ans,d[x]+d[y]+1);
                  d[x]=max(d[x],d[y]+1);
              }
          }
          for(int y:G[x])if(fa[y]!=x)
          {
              if(dfn[x]<dfn[y]) solve(x,y);
          }
      }
      int main()
      {
          int n,m;scanf("%d%d",&n,&m);
          while(m--)
          {
              int k,x,y;scanf("%d%d",&k,&x);k--;
              while(k--)
              {
                  scanf("%d",&y);
                  G[x].push_back(y);G[y].push_back(x);
                  x=y;
              }
          }
          tsp=0;memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));
      	ans=0;tarjan(1,0);
          printf("%d\n",ans);
          return 0;
      }
      • 1

      *【仙人掌】无向连通图的直径[SHOI2008]仙人掌图 II

      信息

      ID
      2676
      时间
      1000ms
      内存
      256MiB
      难度
      6
      标签
      递交数
      29
      已通过
      10
      上传者