zoukankan      html  css  js  c++  java
  • [cf1515G]Phoenix and Odometers

    显然这条路径只能在$v_{i}$所在的强连通分量内部,不妨仅考虑这个强连通分量

    对这个强连通分量dfs,得到一棵外向树(不妨以1为根)

    考虑一条边$(u,v,l)$,由于强连通,总存在一条从$v$到$u$的路径,经过这条路径$t_{i}$次,再经过$u$到$v$这条边$t_{i}-1$次,即从$v$到达了$u$,且总边权$equiv -l(mod t_{i})$

    由此,不妨将$(v,u,-l)$也作为一条边加入图中,显然不影响(以下称这条边为$(u,v,l)$的反向边)

    此时,令$dep_{x}$为1通过树边走到$x$的权值和,那么从$x$到$y$通过树边及其反向边的最短路,权值和即
    $$
    (dep_{lca(x,y)}-dep_{x})+(dep_{y}-dep_{lca(x,y)})=dep_{y}-dep_{x}
    $$
    显然若没有非树边,从$x$到$y$的任意一条路径(之前仅考虑最短路)权值和都为$dep_{y}-dep_{x}$(显然每一条边都是最短路,前后项相消即可)

    考虑非树边$(u,v,l)$,若从$x$到$y$的路径每经过一次$(u,v,l)$,实际上即让边权和加$l-(dep_{v}-dep_{u})$,最后统计所有非树边的贡献和即为总边权和

    另一方面,我们显然可以经过每一条非树边任意次

    由此,对每一条非树边$(u,v,l)$求出$l-(dep_{v}-dep_{u})$,假设依次为$a_{1},a_{2},...,a_{s}$,问题即判定是否存在一组解$x_{i}in N$,使得$sum_{j=1}^{s}x_{j}a_{j}equiv -s_{i}(mod t_{i})$

    根据数论知识,这显然等价于$gcd(gcd_{i=1}^{s}a_{i},t_{i})mid s_{i}$,判定即可

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 200005
     4 #define ll long long
     5 struct Edge{
     6     int nex,to,len;
     7 }edge[N<<1];
     8 int E,n,m,q,x,y,z,scc,head[N],head_rev[N],dfn[N],vis[N],bl[N];
     9 ll dep[N],ans[N];
    10 ll gcd(ll x,ll y){
    11     if (!y)return x;
    12     return gcd(y,x%y);
    13 }
    14 void add(int x,int y,int z){
    15     edge[E].nex=head[x];
    16     edge[E].to=y;
    17     edge[E].len=z;
    18     head[x]=E++;
    19 }
    20 void add_rev(int x,int y,int z){
    21     edge[E].nex=head_rev[x];
    22     edge[E].to=y;
    23     edge[E].len=z;
    24     head_rev[x]=E++;
    25 }
    26 void dfs1(int k){
    27     if (vis[k])return;
    28     vis[k]=1;
    29     for(int i=head[k];i!=-1;i=edge[i].nex)dfs1(edge[i].to);
    30     dfn[++dfn[0]]=k;
    31 }
    32 void dfs2(int k,ll s){
    33     if (bl[k])return;
    34     bl[k]=scc;
    35     dep[k]=s;
    36     for(int i=head_rev[k];i!=-1;i=edge[i].nex)dfs2(edge[i].to,s+edge[i].len);
    37 }
    38 int main(){
    39     scanf("%d%d",&n,&m);
    40     memset(head,-1,sizeof(head));
    41     memset(head_rev,-1,sizeof(head_rev));
    42     for(int i=1;i<=m;i++){
    43         scanf("%d%d%d",&x,&y,&z);
    44         add(x,y,z);
    45         add_rev(y,x,z);
    46     }
    47     for(int i=1;i<=n;i++)
    48         if (!vis[i])dfs1(i);
    49     for(int i=n;i;i--)
    50         if (!bl[dfn[i]]){
    51             scc++;
    52             dfs2(dfn[i],0);
    53         }
    54     for(int x=1;x<=n;x++)
    55         for(int j=head[x];j!=-1;j=edge[j].nex){
    56             y=edge[j].to,z=edge[j].len;
    57             if (bl[x]==bl[y])ans[bl[x]]=gcd(ans[bl[x]],z-(dep[x]-dep[y]));
    58         }
    59     scanf("%d",&q);
    60     for(int i=1;i<=q;i++){
    61         scanf("%d%d%d",&x,&y,&z);
    62         if (y%gcd(ans[bl[x]],z)==0)printf("YES
    ");
    63         else printf("NO
    ");
    64     }
    65 }
    View Code
  • 相关阅读:
    LSTM
    Realsense D435i
    ubuntu18 realsenseD435i
    net
    test
    LSTM Accuracy
    boost x64 lib
    E0443类模板 "std::unordered_set" 的参数太多
    PropertySheet
    freetype 编译
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14873704.html
Copyright © 2011-2022 走看看