zoukankan      html  css  js  c++  java
  • CodeForces

    题意:给定一个n个点m条边的无向图,边权分别为1-m,从起点1出发,每经过一条边就把边权以字符串的形式加入末尾,求到达其他每个点的最小字符串(长度不同的短的更小,否则字典序小的更小)。

    思路很巧妙,将每个边按照边权的位数拆成若干条虚边+若干个虚点,然后以1为起点进行BFS,边权相同的放在一起处理,这样就能保证每个点第一次到达的路径是字符串最小的路径了。

    边权排序可以用基排,因为只能取0-9,常数很小。

    注意各种细节。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e6+10,inf=0x3f3f3f3f,mod=1e9+7;
    int hd[N],ne,n,m,dp[N],tot,buf[N],C[10];
    struct E {int u,v,c,nxt;} e[N<<1];
    void addedge(int u,int v,int c) {e[ne]= {u,v,c,hd[u]},hd[u]=ne++;}
    queue<int> q;
    vector<int> vec,vec2;
    int upd(int u,int x) {
        if(!~dp[u]) {dp[u]=x,q.push(u); return 1;}
        return 0;
    }
    void bfs() {
        memset(dp,-1,sizeof dp);
        while(q.size())q.pop();
        upd(1,0),q.push(-1);
        while(q.size()) {
            vec.clear();
            for(; q.front()!=-1; q.pop())vec.push_back(q.front());
            q.pop();
            vec2.clear();
            for(int u:vec)for(int i=hd[u]; ~i; i=e[i].nxt)vec2.push_back(i);
            for(int i=0; i<=9; ++i)C[i]=0;
            for(int i=0; i<vec2.size(); ++i)++C[e[vec2[i]].c];
            for(int i=1; i<=9; ++i)C[i]+=C[i-1];
            for(int i=0; i<vec2.size(); ++i)buf[--C[e[vec2[i]].c]]=vec2[i];
            for(int i=0,j,k; i<vec2.size(); i=j) {
                for(j=i; j<vec2.size()&&e[buf[j]].c==e[buf[i]].c; ++j);
                int f=0;
                for(k=i; k<j; ++k)if(upd(e[buf[k]].v,((ll)dp[e[buf[k]].u]*10+e[buf[k]].c)%mod))f=1;
                if(f)q.push(-1);
            }
        }
    }
    int main() {
        memset(hd,-1,sizeof hd),ne=0;
        scanf("%d%d",&n,&m);
        tot=n;
        for(int i=1; i<=m; ++i) {
            int u,v;
            scanf("%d%d",&u,&v);
            int c=i;
            if(c/10) {
                addedge(++tot,u,c%10),addedge(++tot,v,c%10),c/=10;
                for(; c/10; c/=10)++tot,addedge(tot,tot-2,c%10),++tot,addedge(tot,tot-2,c%10);
                addedge(v,tot-1,c),addedge(u,tot,c);
            } else addedge(u,v,c),addedge(v,u,c);
        }
        bfs();
        for(int i=2; i<=n; ++i)printf("%d
    ",dp[i]);
        return 0;
    }
  • 相关阅读:
    创建Variant数组
    ASP与存储过程(Stored Procedures)
    FileSystemObject对象成员概要
    Kotlin 朱涛9 委托 代理 懒加载 Delegate
    Kotlin 朱涛 思维4 空安全思维 平台类型 非空断言
    Kotlin 朱涛7 高阶函数 函数类型 Lambda SAM
    Kotlin 朱涛16 协程 生命周期 Job 结构化并发
    Proxy 代理模式 动态代理 cglib MD
    RxJava 设计理念 观察者模式 Observable lambdas MD
    动态图片 Movie androidgifdrawable GifView
  • 原文地址:https://www.cnblogs.com/asdfsag/p/11622980.html
Copyright © 2011-2022 走看看