题目链接:

[APIO2018]铁人两项

对于点双连通分量有一个性质:在同一个点双里的三个点$a,b,c$,一定存在一条从$a$到$c$的路径经过$b$且经过的点只被经过一次。

那么我们建出原图的圆方树,枚举中间点$b$,一对合法的$a,c$需要使这两个点位于与$b$直接相连的方点的不同子树中。树形$DP$,对圆点和方点分别统计答案即可。

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int n,m;
int x,y;
vector<int>q[200010];
int head[100010];
int to[400010];
int next[400010];
int size[200010];
int low[100010];
int dfn[100010];
int tot;
int cnt;
int num;
int st[100010];
int top;
int vis[200010];
ll ans;
int sum;
void add(int x,int y)
{
tot++;
next[tot]=head[x];
head[x]=tot;
to[tot]=y;
}
void insert(int x,int y)
{
q[x].push_back(y);
}
void tarjan(int x)
{
st[++top]=x;
low[x]=dfn[x]=++num;
for(int i=head[x];i;i=next[i])
{
if(!dfn[to[i]])
{
tarjan(to[i]);
low[x]=min(low[x],low[to[i]]);
if(low[to[i]]>=dfn[x])
{
insert(++cnt,x);
insert(x,cnt);
int now=0;
do
{
now=st[top--];
insert(cnt,now);
insert(now,cnt);
}
while(now!=to[i]);
}
}
else
{
low[x]=min(low[x],dfn[to[i]]);
}
}
}
void dfs(int x,int fa)
{
vis[x]=1;
size[x]=(x<=n?1:0);
int len=q[x].size();
for(int i=0;i<len;i++)
{
int to=q[x][i];
if(to!=fa)
{
dfs(to,x);
size[x]+=size[to];
}
}
}
void tree_dp(int x,int fa)
{
int len=q[x].size();
for(int i=0;i<len;i++)
{
int to=q[x][i];
if(to!=fa)
{
tree_dp(to,x);
}
}
if(x<=n)
{
for(int i=0;i<len;i++)
{
int to=q[x][i];
if(to!=fa)
{
ans+=1ll*size[to]*(sum-size[to]-1);
}
else
{
ans+=1ll*(sum-size[x])*(size[x]-1);
}
}
}
else if(len>=3)
{
for(int i=0;i<len;i++)
{
int to=q[x][i];
if(to!=fa)
{
ans+=1ll*size[to]*(sum-size[to])*(len-2);
}
else
{
ans+=1ll*(sum-size[x])*size[x]*(len-2);
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);cnt=n;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i])
{
tarjan(i);
}
}
for(int i=1;i<=cnt;i++)
{
if(!vis[i])
{
dfs(i,0);
sum=size[i];
tree_dp(i,0);
}
}
printf("%lld",ans);
}

最新文章

  1. EF多对多更新报错(TableNoTracking引发的bug)
  2. jQuery Mobile + HTML5
  3. RabbitMQ学习笔记5-简单的RPC调用
  4. oracle RAC调整数据文件大小并移动表到指定的表空间
  5. 用XAML做网页!!—广告展示区
  6. [模版]平衡树splay2
  7. linux线程(一)
  8. GIT-windows系统部署git服务器
  9. WEB学习笔记11-高可读性的HTML之如何设置网页标题层级
  10. Hulu大规模容器调度系统Capos
  11. Redis事物
  12. Bugku-CTF之变量1
  13. Springmvc 简单入门1
  14. c++中浮点数精度设置
  15. Windows 2008驱动安装失败的原因及解决方法
  16. BZOJ 1211[HNOI2004]树的计数 - prufer数列
  17. freemarker多个checkbox一个以上被选中示例
  18. 关于构造器和Serlvet的知识点
  19. IC设计前后端流程与EDA工具
  20. 子集和问题(应用--换零钱)POJ2229:Sumsets

热门文章

  1. js时间格式化和相互转换
  2. oracle 01741:非法的零长度标识
  3. Redis for C#
  4. PHP设置谷歌验证器(Google Authenticator)实现操作二步验证
  5. rhel7下安装EPEL源
  6. linux防火墙(一)
  7. [ipsec][strongswan] strongswan源码分析--(四)plugin加载优先级原理
  8. 【20191118会议】针对华为云CCE 问题总结
  9. 【OF框架】搭建标准工作环境
  10. grafana忘记登陆密码