[题目链接]

https://www.lydsy.com/JudgeOnline/problem.php?id=1791

[算法]

不难看出,要求的是这个基环树森林中每棵基环树的直径之和

[代码]

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + ; struct edge
{
int to,w,nxt;
} e[MAXN << ]; int i,v,w,tot,n,u,cnt;
int degree[MAXN],belong[MAXN],head[MAXN];
long long d[MAXN],f[MAXN],a[MAXN << ],sum[MAXN << ];
long long ans;
bool cal[MAXN]; inline void addedge(int u,int v,int w)
{
tot++;
e[tot] = (edge){v,w,head[u]};
head[u] = tot;
}
inline void bfs(int u,int t)
{
int i,cur,v,w;
queue< int > q;
belong[u] = t;
q.push(u);
while (!q.empty())
{
cur = q.front();
q.pop();
for (i = head[cur]; i; i = e[i].nxt)
{
v = e[i].to;
w = e[i].w;
if (!belong[v])
{
belong[v] = t;
q.push(v);
}
}
}
}
inline void topsort()
{
int i,u,v,w;
queue< int > q;
for (i = ; i <= n; i++)
{
if (degree[i] == )
q.push(i);
}
while (!q.empty())
{
u = q.front();
q.pop();
for (i = head[u]; i; i = e[i].nxt)
{
v = e[i].to;
w = e[i].w;
if (degree[v] > )
{
d[belong[u]] = max(d[belong[u]],f[u] + f[v] + w);
f[v] = max(f[v],f[u] + w);
if ((--degree[v]) == ) q.push(v);
}
}
}
}
inline void dp(int t,int x)
{
long long i,l,r,y = x,m = ,v,w;
static int q[MAXN << ];
do
{
a[++m] = f[y];
degree[y] = ;
for (i = head[y]; i; i = e[i].nxt)
{
v = e[i].to;
w = e[i].w;
if (degree[v] > )
{
y = v;
sum[m + ] = sum[m] + w;
break;
}
}
} while(i);
if (m == )
{
l = ;
for (i = head[y]; i; i = e[i].nxt)
{
v = e[i].to;
w = e[i].w;
if (v == x) l = max(l,w);
}
d[t] = max(d[t],f[x] + f[y] + l);
return;
}
for (i = head[y]; i; i = e[i].nxt)
{
v = e[i].to;
w = e[i].w;
if (v == x)
{
sum[m + ] = sum[m] + w;
break;
}
}
for (i = ; i < m; i++)
{
a[m + i] = a[i];
sum[m + i] = sum[m + ] + sum[i];
}
q[l = r = ] = ;
for (i = ; i <= * m - ; i++)
{
while (l <= r && i - q[l] >= m) l++;
d[t] = max(d[t],a[q[l]] + a[i] + sum[i] - sum[q[l]]);
while (l <= r && a[q[r]] - sum[q[r]] <= a[i] - sum[i]) r--;
q[++r] = i;
}
}
int main()
{ scanf("%d",&n);
for (u = ; u <= n; u++)
{
scanf("%d%d",&v,&w);
addedge(u,v,w);
addedge(v,u,w);
degree[u]++; degree[v]++;
}
for (i = ; i <= n; i++)
{
if (!belong[i])
bfs(i,++cnt);
}
topsort();
for (i = ; i <= n; i++)
{
if (degree[i] > && !cal[belong[i]])
{
cal[belong[i]] = true;
dp(belong[i],i);
ans += d[belong[i]];
}
}
printf("%lld\n",ans); return ; }

最新文章

  1. SQL 优化总结
  2. ASP.NET MVC 快速开发框架之 SqlSugar+SyntacticSugar+JQWidgetsSugar+jqwidgets(转)
  3. java GUI之基本图形
  4. Javascript单元测试框架比较Qunit VS Jasmine
  5. tkinter做一个简单的登陆页面
  6. [Swift]LeetCode778. 水位上升的泳池中游泳 | Swim in Rising Water
  7. 【Dubbo 源码解析】02_Dubbo SPI
  8. 【未解决】对于使用Windows的IDEA进行编译的文件,但无法在Linux系统中统计代码行数的疑问
  9. spring-mybatis-data-common程序级分表操作实例
  10. 使用 mysql_use_result 还是使用 mysql_store_result?
  11. hdu1243 dp (类最长公共子序列)
  12. poj 2774 后缀数组 两个字符串的最长公共子串
  13. Real-time 3D Reconstruction using Kinect
  14. Javascript-自己定义对象转换成JSon后怎样再转换回自己定义对象
  15. SQL编程:group by合并结果字符串 ---&gt; group_concat函数就能行
  16. 【OCP-12c】2019年CUUG OCP 071考试题库(74题)
  17. log4net始终占用日志文件的问题
  18. LR----实现WebService测试
  19. CDH5.10 添加kafka服务
  20. Resources.FindObjectsOfTypeAll&lt;T&gt;()的坑(Ghost prefab)

热门文章

  1. vue-cli脚手架安装过程(精简版)
  2. 【MySQL】通信协议
  3. CDC之fast-&gt;slow (2)
  4. 统计:mAP的中文意思
  5. 【C++】颜色的设置
  6. C#如何判断操作系统语言版本
  7. 递归删除List元素
  8. java输入输入流图解
  9. 用Python来实现斐波那契数列.
  10. vue中用v-for循环出出来的div下面的span不给宽度也能相对于div居中