CF1515G
CF1515G Phoenix and Odometers
首先进行缩点,对于一个点,与它不在同一连通分量的点无法形成回路,所以对每个连通分量分别计算。
假设一个点
考虑如何求出
首先在强连通分量中存在四种边:树边、横叉边、返祖边、前向边。
举个例子:
假设根节点为
以横叉边
所以其中一条回路为
又因为当前的横叉边
这两条回路的 gcd,可以使用辗转相减进行化简,将公共路径部分减掉,则 gcd 为
这样对于一条横叉边
然后通过分析发现,返祖边和前向边对 gcd 的贡献也是
求出所有环长的 gcd,设为
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,q;
const int maxn=2e5+10;
struct node{
int to,nxt,w;
};
node e[maxn];
int head[maxn],tot;
void add(int u,int v,int w){
++tot;
e[tot].to=v;
e[tot].nxt=head[u];
e[tot].w=w;
head[u]=tot;
}
int dfn[maxn],low[maxn],st[maxn];
bool vis[maxn];
int scc[maxn];
int res,tp,cnt;
void tarjan(int u){
dfn[u]=low[u]=++res;
st[++tp]=u;
vis[u]=1;
for(int i=head[u];i!=0;i=e[i].nxt){
int v=e[i].to;
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(vis[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u]){
++cnt;
while(st[tp]!=u){
scc[st[tp]]=cnt;
vis[st[tp]]=0;
--tp;
}
scc[st[tp]]=cnt;
vis[st[tp]]=0;
--tp;
}
}
int dis[maxn],g[maxn];
bool tag[maxn];
void dfs(int u,int cur){
tag[u]=1;
for(int i=head[u];i!=0;i=e[i].nxt){
int v=e[i].to;
int w=e[i].w;
if(scc[v]!=cur){
continue;
}
if(tag[v]){
g[cur]=__gcd(g[cur],dis[u]-dis[v]+w);
continue;
}
dis[v]=dis[u]+w;
dfs(v,cur);
}
}
signed main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=m;i++){
int u,v,w;
scanf("%lld%lld%lld",&u,&v,&w);
add(u,v,w);
}
for(int i=1;i<=n;i++){
if(!dfn[i]){
tarjan(i);
}
}
for(int i=1;i<=n;i++){
if(!tag[i]){
dfs(i,scc[i]);
}
}
scanf("%lld",&q);
while(q--){
int u,s,t;
scanf("%lld%lld%lld",&u,&s,&t);
if(s%__gcd(g[scc[u]],t)==0){
printf("YES\n");
}
else{
printf("NO\n");
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现