题目链接
- 基环树的直径
- 两种情况:不经过环和经过环
- 找环方法:深度优先遍历+限制回溯
- 【注】较为简便的方法是记录一条边是否被访问过,但由于本题卡时卡空间,为了节省掉代替成对变换的vector数组,代码中只能将其替换为复杂的逻辑判断
- 归并环上顺、逆时针两种情况:断环为链再复制一倍
- 用deque实现单调队列
- 给环上的每个节点打上特定标记,既能实现对基环树森林的枚举,又能得到每个环上的所有节点
- 分部调试
- 尽可能利用已有变量的编程原则
点击查看代码
#include <bits/stdc++.h>
using namespace std;
vector<int>a[1000005];
vector<int>c[1000005];
vector<int>z[500005];
vector<int>w[500005];
long long sw[1000005];
int m,g;
long long ans,d[1000005];
int h[1000005],r[1000005];
bool v[1000005];
deque<int>q;
int dfs(int n1,int fa,int va)
{
bool f=false,b=false;
v[n1]=true;
for(int i=0;i<a[n1].size();i++)
{
if(a[n1][i]!=fa&&h[a[n1][i]]==0||a[n1][i]==fa&&r[n1]==a[n1][i]&&r[a[n1][i]]==n1&&(va!=c[n1][i]||b==true))
{
if(v[a[n1][i]]==false)
{
int tmp=dfs(a[n1][i],n1,c[n1][i]);
if(tmp>0)
{
if(h[n1]==tmp)
{
f=true;
}
h[n1]=tmp;
z[h[n1]].push_back(n1);
w[h[n1]].push_back(c[n1][i]);
}
}
else
{
m++;
h[n1]=m;
z[m].push_back(n1);
w[m].push_back(c[n1][i]);
h[a[n1][i]]=m;
}
}
if(a[n1][i]==fa&&r[n1]==a[n1][i]&&r[a[n1][i]]==n1&&va==c[n1][i])
{
b=true;
}
}
if(f==true)
{
return 0;
}
return h[n1];
}
void dp(int n1,int fa)
{
for(int i=0;i<a[n1].size();i++)
{
if(h[a[n1][i]]==0&&a[n1][i]!=fa)
{
dp(a[n1][i],n1);
ans=max(ans,d[n1]+d[a[n1][i]]+c[n1][i]);
d[n1]=max(d[n1],d[a[n1][i]]+c[n1][i]);
}
}
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
int v=read1();
int w=read1();
a[i].push_back(v);
a[v].push_back(i);
c[i].push_back(w);
c[v].push_back(w);
r[i]=v;
}
for(int i=1;i<=n;i++)
{
if(!v[i])
{
int tmp=dfs(i,0,0);
}
}
long long sum=0;
for(int i=1;i<=m;i++)
{
ans=0;
for(int j=0;j<z[i].size();j++)
{
dp(z[i][j],0);
}
q.push_back(0);
g=z[i].size();
long long s=w[i][0];
int cnt=0;
sw[0]=s;
for(int j=1;j<2*g;j++)
{
s=s+w[i][j%g];
cnt++;
sw[cnt]=s;
int m1=q.front();
if(m1==j-g)
{
q.pop_front();
m1=q.front();
}
int u=z[i][m1%g];
long long cur=sw[j]-sw[m1];
int n1=z[i][j%g];
ans=max(ans,d[u]+cur+d[n1]);
while(!q.empty())
{
int m1=q.back();
int u=z[i][m1%g];
long long cur=sw[j]-sw[m1];
if(d[n1]>=d[u]+cur)
{
q.pop_back();
}
else
{
break;
}
}
q.push_back(j);
}
q.clear();
sum+=ans;
}
cout<<sum<<endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现