标题给自己加场戏
新年快乐各位
懒得写学期总结
不会起标题了
昨晚今早做的,补一下题解
就是让你求一个图有多少个三元组
那么,当一个点到另一个点经过点双时,点双里的任何一点都可以作为中转点
所以缩点
但缩完点点双内部就不好处理了
所以给他建成圆方树
圆方树可以做到把简单无向图转换为我们熟悉的树结构,从而进行一些树上的操作,所以我们在遇到这种图时会想到圆方树
把方点的权值设为点双的点的个数
就变成了
求两个圆点之间的点权和
容斥掉两个端点和交界处的点(割点)
所以给圆点权值附上 -1(连接几个点双的就是割点)
一开始我用了一个非常麻烦的做法……
其实就先算子树之间的贡献,再算祖先和子树的贡献就行
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+6;
int n,m,head[N],cnt,head1[N],cnt1,ans;
struct node{int to,nxt;}e[N],e1[N];
void add(int u,int v){
e[++cnt].to=v;
e[cnt].nxt=head[u];
head[u]=cnt;
}
void add1(int u,int v){
e1[++cnt1].to=v;
e1[cnt1].nxt=head1[u];
head1[u]=cnt1;
}
int dfn[N],low[N],tim,st[N],top,tot,val[N],siz[N];
bool vis[N];
int subn=0;
void tarjan(int u,int fa){
subn++;
st[++top]=u;
dfn[u]=low[u]=++tim;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v==fa)continue;
if(!dfn[v]){
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]){//割点是>= 割边是>
++tot;
int va=0;
for(int p=0;p!=v;top--){
va++;
p=st[top];
val[p]=-1;
add1(tot,p),add1(p,tot);
// cout<<tot<<" "<<p<<endl;
}
val[u]=-1;
add1(tot,u),add1(u,tot);
//cout<<tot<<" "<<u<<endl;
val[tot]=va+1;
}
}
else low[u]=min(low[u],dfn[v]);
}
}
void dfs(int u,int f){
siz[u]=(u<=n);
for(int i=head1[u];i;i=e1[i].nxt){
int v=e1[i].to;
if(v==f)continue;
dfs(v,u);
ans+=val[u]*siz[v]*siz[u];
siz[u]+=siz[v];
// cout<<u<<" "<<val[u]*siz[v]*(siz[rt]-siz[v]-(u<=n))<<endl;
}
ans+=val[u]*siz[u]*(subn-siz[u]);
}
signed main(){
cin>>n>>m;
tot=n;
for(int i=1;i<=m;i++){
int u,v;
cin>>u>>v;
add(u,v),add(v,u);
}
for(int i=1;i<=n;i++){
if(!dfn[i]){
subn=0;
tarjan(i,0),dfs(i,0);
}
}
cout<<ans*2;
return 0;
}
诺宇找到了她的小说本
(如果在某小说网上找到了诺宇|诺麟瑜宇|冷瑜麟,那就是我)
(冷瑜麟是诺宇小说的主人公,并客串了数本小说,至于为啥叫这名字……)
(离谱的是诺宇到现在都没想好冷瑜麟是男是女)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探