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