• XJOI网上同步训练DAY6 T1


    思路:考试的时候直接想出来了,又有点担心复杂度,不过还是打了,居然是直接A掉,开心啊。

    我们发现,Ai<=7,这一定是很重要的条件,我们考虑状态压缩,去枚举路径中出现了哪些数字,然后我们把原来n个点拆成 我们枚举数字的最小公倍数 个,因为如果一个数模某个数等于0,那么模它的因数也一定是0,因此我们的思路就是拆点最短路。

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<iostream>
     6 const int p[25]={1,2,3,4,5,6,7,10,12,14,15,20,21,28,30,35,42,60,70,84,105,140,210,420};
     7 int tot,go[200005],first[200005],next[200005];
     8 struct edge{
     9     int u,v;
    10 }e[50005];
    11 int a[200005],n,m,vis[5005][505],dis[5005][505],c[2000005][2];
    12 int read(){
    13      int t=0,f=1;char ch=getchar();
    14      while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    15      while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
    16      return t*f;
    17 }
    18 void insert(int x,int y){
    19      tot++;
    20      go[tot]=y;
    21      next[tot]=first[x];
    22      first[x]=tot;
    23 }
    24 void add(int x,int y){
    25      insert(x,y);insert(y,x);
    26 }
    27 int gcd(int a,int b){
    28      if (b==0) return a;
    29          else return gcd(b,a%b);
    30 }
    31 void build(int Mod){
    32     for (int i=1;i<=n;i++) first[i]=0;tot=0;
    33     for (int i=1;i<=m;i++){
    34         if (Mod%a[e[i].u]!=0) continue;
    35         if (Mod%a[e[i].v]!=0) continue;
    36         add(e[i].u,e[i].v);
    37     }
    38 }
    39 int spfa(int Mod){
    40      build(Mod);
    41      for (int i=1;i<=n;i++)
    42       for (int j=0;j<Mod;j++)
    43        dis[i][j]=0x3f3f3f3f,vis[i][j]=0;
    44      int h=1,t=1;c[h][0]=1;c[h][1]=a[1]%Mod;
    45      vis[1][0]=1;dis[1][a[1]%Mod]=a[1]; 
    46      while (h<=t){
    47             int nowx=c[h][0],nowy=c[h++][1];
    48             for (int i=first[nowx];i;i=next[i]){
    49                 int pur1=go[i],pur2=((nowy*10%Mod)+a[pur1])%Mod;
    50                 if (dis[pur1][pur2]>dis[nowx][nowy]+a[pur1]){
    51                     dis[pur1][pur2]=dis[nowx][nowy]+a[pur1];
    52                     if (vis[pur1][pur2]) continue;
    53                     vis[pur1][pur2]=1;
    54                     t++;
    55                     c[t][0]=pur1;c[t][1]=pur2;
    56                 }
    57             }
    58             vis[nowx][nowy]=0;
    59      }
    60     return dis[n][0];
    61 }
    62 void solve(){
    63      int ans=0x3f3f3f3f;
    64      int sb=a[1]*a[n]/gcd(a[1],a[n]);
    65      for (int i=0;i<24;i++)
    66       if (p[i]%sb==0){
    67         ans=std::min(ans,spfa(p[i]));
    68       }
    69      if (ans==0x3f3f3f3f) ans=-1;
    70      printf("%d
    ",ans);
    71 }
    72 int main(){
    73      int T=read();
    74      while (T--){
    75         n=read();m=read();
    76         for (int i=1;i<=n;i++) first[i]=0;tot=0;
    77         for (int i=1;i<=n;i++) a[i]=read();
    78         for (int i=1;i<=m;i++){
    79              e[i].u=read();e[i].v=read();
    80         }
    81         solve();
    82      }
    83 }
  • 相关阅读:
    20210110-正则表达式
    20210105
    C# Expression 树转化为SQL语句(一)
    5000行js db
    Keras智能
    nginx 设置多个tcp IP代理 socket 转发
    FTP连接时出现“227 Entering Passive Mode” 的解决方法
    windows nginx TCP代理 负载均衡
    nginx 代理ftp
    Intellij IDEA添加项目依赖
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5633101.html
Copyright © 2020-2023  润新知