zoukankan      html  css  js  c++  java
  • Codeforces 1209F. Koala and Notebook

    传送门

    考虑到达某个点时的数长度要尽量短,那么可以把边长看成此边十进制下的位数

    那么对于最终答案我们只要考虑最短路 $DAG$ 上的情况

    又发现其实边长都很小,所以可以暴力拆边,把边权都拆成 $1$,这样就可以 $BFS$ 了

    考虑最优情况,对于 $BFS$ 时同一层的点,要扩展到下一层,我们肯定要优先让边的数字为 $1$ 的边先走

    然后剩下走 $1$ 到不了的点我们再试着走 $2$,然后 $3$ ,$4$ ... 这样下去,这样到达下一层以后每个点的路径才是最优的

    所以我们就要一些比较神仙的操作来实现这个过程...我可能也讲不清楚了,自己看代码吧

    代码参考:wxhtxdy

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<vector>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=1e6+7,mo=1e9+7;
    int n,m,tot,ans[N];
    vector <int> e,V[N][10],Q[N];//V是边,Q是BFS的队列,队列为啥是vector等等就知道了...
    bool vis[N];
    int main()
    {
        n=read(),m=read(); int a,b;
        tot=n;
        for(int i=1;i<=m;i++)
        {
            a=read(),b=read(); int t=i,c; e.clear();
            while(t) c=t%10,t/=10,e.push_back(c);
            reverse(e.begin(),e.end()); int pre=a,len=e.size();
            for(int j=0;j<len;j++)//拆点
            {
                int np=(j==len-1 ? b : ++tot);
                V[pre][e[j]].push_back(np),pre=np;
            }
            pre=b;
            for(int j=0;j<len;j++)//无向图两边都要拆
            {
                int np=(j==len-1 ? a : ++tot);
                V[pre][e[j]].push_back(np),pre=np;
            }
        }
        int T=0; Q[++T].push_back(1); vis[1]=1;
        for(int i=1;i<=T;i++)
            for(int j=0;j<=9;j++)//优先走数字小的
            {
                bool flag=0;
                for(auto x: Q[i])//对于同一个i,Q[i]中的点的ans都是一样的
                    for(auto v: V[x][j])//走到下一层
                    {
                        if(vis[v]) continue;//走过就不用再走了
                        vis[v]=flag=1; Q[T+1].push_back(v);
                        ans[v]=(10ll*ans[x]+j)%mo;//更新答案
                    }
                if(flag) T++;
            }
        for(int i=2;i<=n;i++) printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    更改桌面位置
    三国杀高级技巧!!
    excel中删除空白行方法
    欢迎来稿
    coreseek配置文件分析
    html中a连接触发表单提交
    html点击按钮动态添加input文本框
    页面表单预览数据传递注意事项
    mysql 主从复制(masterslave)
    mysql explain key_len小结
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11526581.html
Copyright © 2011-2022 走看看