题解:Many Many Cycles
1.题解:P9923 [POI 2023/2024 R1] Przyciski2.题解:P6544 [CEOI2014] Cake3.题解:CF690A2 Collective Mindsets (medium)4.题解:AT_arc050_c [ARC050C] LCM 1115.题解:P11311 漫长的小纸带6.题解:CF815D Karen and Cards7.题解:AT_abc389_e [ABC389E] Square Price8.题解:P11490 [BalticOI 2023] Staring Contest9.题解:[ABC355E] Guess the Sum10.题解:AT_abc283_g [ABC283G] Partial Xor Enumeration11.题解:P2540 [NOIP2015 提高组] 斗地主 加强版12.题解:AT_abc373_g [ABC373G] No Cross Matching13.题解:P4026 [SHOI2008] 循环的债务14.题解:P11644 【MX-X8-T3】「TAOI-3」地地爱打卡15.题解:P11617 递推16.题解:[AGC054D] (ox)17.题解:Minimize Inversions Number
18.题解:Many Many Cycles
19.CF Round 1001 题解合集20.题解:The Game (Easy Version & Hard Version)21.abc391 题解合集22.题解:[AGC044D] Guess the Password23.题解:Coprime Permutation24.题解:[THUPC 2021] 鬼街25.题解:P8393 [BalticOI 2022] Stranded Far From Home (Day2)26.题解:P9989 [Ynoi Easy Round 2023] TEST_6927.题解:mex times mex(省选模拟赛 T2)28.abc392 题解合集29.S2OJ 20250211 题解合集30.CF Round 1004 题解合集31.CF Round 1002 题解合集32.abc393 题解合集33.CF Round 1005 题解合集34.CF Round 997 题解合集35.CF Round 999 题解合集36.CF Round 998 题解合集37.CF Edu Round 174 题解合集38.2025 USACO Feb 银组题解合集39.S2OJ 20250223 题解合集前言
好题。
第一次听说切边等价。
思路分析
首先玩两个环的情况。令环长分别为 ,重合部分的长度为 ,那么答案为:
对于大于两个环的情况,我们可以任意拆解成两个环的情况,再进行计算。
因此,我们只需要找出若干个简单环,以及它们的切边等价类,按题意取 即可。
实现上,可以找出原图的一个生成森林,对于每个由一条非树边构成的环,我们求出环长,同时用树上差分异或哈希维护切边等价类,也就是若干环的极大共同重合部分,因为需要求 lca,所以复杂度为 。
代码实现
注意特判只有一个环的等价类,它们不属于环的重合部分,不应该被统计到答案里。
#include<bits/stdc++.h>
#define int long long
using namespace std;
mt19937 rnd(time(0));
int n,m,gcd,c[10005],d[10005],h[10005],x[10005],y[10005],w[10005],e[10005],vis[10005];
int fa[5005],num[5005];
void init(){
for(int i=1;i<=n;i++){
fa[i]=i;
num[i]=h[i];
}
}
int find(int x){
if(fa[x]==x) return x;
else return fa[x]=find(fa[x]);
}
void merge(int x,int y){
x=find(x);
y=find(y);
if(x==y) return;
fa[x]=y;
num[y]+=num[x];
}
int head[5005],nxt[20005],targetx[20005],targetw[200005],tot;
void add(int x,int y,int w){
tot++;
nxt[tot]=head[x];
head[x]=tot;
targetx[tot]=y;
targetw[tot]=w;
}
int siz[5005],dep[5005],dfn[5005],dis[5005],rnk[5005],top[5005],hson[5005],f[5005],cnt;
void dfs1(int x,int fa){
siz[x]=1;
for(int i=head[x];i;i=nxt[i]){
int y=targetx[i],w=targetw[i];
if(y==fa) continue;
dep[y]=dep[x]+1;
dis[y]=dis[x]+w;
f[y]=x;
h[y]=w;
dfs1(y,x);
siz[x]+=siz[y];
if(siz[hson[x]]<siz[y]) hson[x]=y;
}
}
void dfs2(int x,int t){
top[x]=t;
cnt++;
dfn[x]=cnt;
rnk[cnt]=x;
if(!hson[x]) return;
dfs2(hson[x],t);
for(int i=head[x];i;i=nxt[i]){
int y=targetx[i],w=targetw[i];
if(y==f[x] || y==hson[x]) continue;
dfs2(y,y);
}
}
int lca(int x,int y){
while(top[x]^top[y]){
if(dep[top[x]]>dep[top[y]]) x=f[top[x]];
else y=f[top[y]];
}
if(dfn[x]<dfn[y]) return x;
else return y;
}
void dfs3(int x,int fa){
vis[x]=1;
for(int i=head[x];i;i=nxt[i]){
int y=targetx[i];
if(y==fa) continue;
dfs3(y,x);
c[x]^=c[y];
d[x]+=d[y];
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
init();
for(int i=1;i<=m;i++){
cin>>x[i]>>y[i]>>w[i];
e[i]=rnd();
if(find(x[i])!=find(y[i])){
add(x[i],y[i],w[i]);
add(y[i],x[i],w[i]);
merge(x[i],y[i]);
}else{
vis[i]=1;
}
}
for(int i=1;i<=n;i++){
if(!siz[i]){
dfs1(i,0);
dfs2(i,i);
}
}
for(int i=1;i<=m;i++){
if(vis[i]){
gcd=__gcd(gcd,dis[x[i]]+dis[y[i]]-2*dis[lca(x[i],y[i])]+w[i]);
c[x[i]]^=e[i];
c[y[i]]^=e[i];
d[x[i]]++;
d[y[i]]++;
d[lca(x[i],y[i])]-=2;
}
}
for(int i=1;i<=n;i++){
vis[i]=0;
}
for(int i=1;i<=n;i++){
if(!vis[i]){
dfs3(i,0);
}
}
init();
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(c[i]==c[j]) merge(i,j);
}
}
for(int i=1;i<=n;i++){
if(d[i]>=2 && find(i)==i) gcd=__gcd(gcd,num[i]<<1);
}
cout<<gcd;
return 0;
}
本文作者:Kenma
本文链接:https://www.cnblogs.com/Kenma/p/18698586
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
合集:
题解
, 2025.2 上海复旦勰码集训
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步