zoukankan      html  css  js  c++  java
  • 4537: [Hnoi2016]最小公倍数

    Description

      给定一张N个顶点M条边的无向图(顶点编号为1,2,…,n),每条边上带有权值。所有权值都可以分解成2^a*3^b
    的形式。现在有q个询问,每次询问给定四个参数u、v、a和b,请你求出是否存在一条顶点u到v之间的路径,使得
    路径依次经过的边上的权值的最小公倍数为2^a*3^b。注意:路径可以不是简单路径。下面是一些可能有用的定义
    :最小公倍数:K个数a1,a2,…,ak的最小公倍数是能被每个ai整除的最小正整数。路径:路径P:P1,P2,…,Pk是顶
    点序列,满足对于任意1<=i<k,节点Pi和Pi+1之间都有边相连。简单路径:如果路径P:P1,P2,…,Pk中,对于任意1
    <=s≠t<=k都有Ps≠Pt,那么称路径为简单路径。

    Input

      输入文件的第一行包含两个整数N和M,分别代表图的顶点数和边数。接下来M行,每行包含四个整数u、v、a、
    b代表一条顶点u和v之间、权值为2^a*3^b的边。接下来一行包含一个整数q,代表询问数。接下来q行,每行包含四
    个整数u、v、a和b,代表一次询问。询问内容请参见问题描述。1<=n,q<=50000、1<=m<=100000、0<=a,b<=10^9

    Output

      对于每次询问,如果存在满足条件的路径,则输出一行Yes,否则输出一行 No(注意:第一个字母大写,其余
    字母小写) 。

    Sample Input

    4 5
    1 2 1 3
    1 3 1 2
    1 4 2 1
    2 4 3 2
    3 4 2 2
    5
    1 4 3 3
    4 2 2 3
    1 3 2 2
    2 3 2 2
    1 3 4 4

    Sample Output

    Yes
    Yes
    Yes
    No
    No

     

    题解:

    http://blog.csdn.net/thy_asdf/article/details/51203421

    注意并查集不能路径压缩,要用启发式合并

    code:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 char ch;
     8 bool ok;
     9 void read(int &x){
    10     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    11     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    12     if (ok) x=-x;
    13 }
    14 const int maxn=150005;
    15 int n,m,q,rm,tot,cnt,fa[maxn],siz[maxn],maxa[maxn],maxb[maxn];
    16 int find(int x){return x==fa[x]?x:find(fa[x]);}
    17 bool ans[maxn];
    18 struct Data{
    19     int u,v,a,b,id;
    20     void init(int i){read(u),read(v),read(a),read(b),id=i;}
    21 }edge[maxn],quer[maxn],tmp[maxn];
    22 bool cmpa(const Data &x,const Data &y){return x.a<y.a||(x.a==y.a&&x.b<y.b);}
    23 bool cmpb(const Data &x,const Data &y){return x.b<y.b||(x.b==y.b&&x.a<y.a);}
    24 struct Oper{
    25     int u,v,fa,siz,ma,mb;
    26 }oper[maxn];
    27 void merge(int u,int v,int a,int b){
    28     u=find(u),v=find(v);
    29     if (siz[u]>siz[v]) swap(u,v);
    30     oper[++cnt]=(Oper){u,v,fa[u],siz[v],maxa[v],maxb[v]};
    31     if (u==v) maxa[u]=max(maxa[u],a),maxb[u]=max(maxb[u],b);
    32     else fa[u]=v,siz[v]+=siz[u],maxa[v]=max(maxa[v],max(maxa[u],a)),maxb[v]=max(maxb[v],max(maxb[u],b));
    33 }
    34 void undo(){
    35     for (;cnt;cnt--){
    36         fa[oper[cnt].u]=oper[cnt].fa;
    37         maxa[oper[cnt].v]=oper[cnt].ma;
    38         maxb[oper[cnt].v]=oper[cnt].mb;
    39         siz[oper[cnt].v]=oper[cnt].siz;
    40     }
    41 }
    42 int main(){
    43     read(n),read(m),rm=sqrt(m);
    44     for (int i=1;i<=m;i++) edge[i].init(i);
    45     sort(edge+1,edge+m+1,cmpa);
    46     read(q);
    47     for (int i=1;i<=q;i++) quer[i].init(i);
    48     sort(quer+1,quer+q+1,cmpb);
    49     for (int i=1;i<=m;i+=rm){
    50         tot=0;
    51         for (int j=1;j<=q;j++) if (edge[i].a<=quer[j].a&&(i+rm>m||quer[j].a<edge[i+rm].a)) tmp[++tot]=quer[j];
    52         sort(edge+1,edge+i,cmpb);
    53         for (int j=1;j<=n;j++) fa[j]=j,siz[j]=1,maxa[j]=maxb[j]=-1;
    54         for (int j=1,k=1;j<=tot;j++){
    55             for (;k<i&&edge[k].b<=tmp[j].b;k++) merge(edge[k].u,edge[k].v,edge[k].a,edge[k].b);
    56             cnt=0;
    57             for (int p=i;p<i+rm&&p<=m;p++) if (edge[p].a<=tmp[j].a&&edge[p].b<=tmp[j].b)
    58                 merge(edge[p].u,edge[p].v,edge[p].a,edge[p].b);
    59             int x=find(tmp[j].u),y=find(tmp[j].v);
    60             ans[tmp[j].id]=(x==y&&maxa[x]==tmp[j].a&&maxb[x]==tmp[j].b);
    61             undo();
    62         }
    63     }
    64     for (int i=1;i<=q;i++) if (ans[i]) puts("Yes"); else puts("No");
    65     return 0;
    66 }
  • 相关阅读:
    Linux如何查找大文件或目录总结
    Linux下动态调整LVM文件系统大小
    ios学习路线图
    js模块,类,继承,命名空间,私有属性等相关概念梳理
    <代码大全2>记录
    2017读书计划
    Spring声明式事务
    Spring-Aop
    Spring静态工厂和扫描器
    Spring-IOC
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/5416868.html
Copyright © 2011-2022 走看看