• 香港记者 图论


    1 问题描述 众所周知,香港记者跑得比谁都快,这其中其实是有秘诀的。 首先他们会跑最短路,但是最短路会有很多条,而且其他记者也知道要跑最短路,香港记者 还统计出了每座城市带黑框眼镜的人数,如果一个记者跑路的时候城市带黑框眼镜人数的序列 字典序比另一个记者大,那么这个记者就会被不可描述的力量续走时间,导致他跑得没字典序 小的记者快。 长者日续万秒日理万机,想请你告诉他香港记者经过的总路程和城市带黑框眼镜人数的序 列,方便他找到香港记者,传授他们一些人生经验。 方便起见,设起点为 1 终点为 n。 由于续命的多样性不可描述的力量,各个城市带黑框眼镜的人数各不相同。

    2 输入格式 输入文件名为 journalist.in。 第一行,两个整数 n, m 表示有 n 个城市,城市之间有 m 条有向边。 第二行,n 个数,表示每个城市带黑框眼镜的人数 bi: 接下来 m 行,每行 3 个非负整数 ui , vi , wi 表示一条有向边的起点,终点,路程。

    3 输出格式 输出文件名为 journalist.out。 第一行,一个非负整数表示香港记者经过的总路程。 第二行,若干个非负整数表示香港记者经过的城市带黑框眼镜人数的序列。

    4 样例 见下发/journalist/journalist.in(out)。 5 数据规模与约定 对于前 30% 的数据,2 ≤ n ≤ 2 × 103,1 ≤ m ≤ 4 × 103。 对于前 60% 的数据,保证数据随机。 对于另外 30% 的数据,保证所有起点到终点的简单路径(没有环的路径)长度相同。 对于 100% 的数据,2 ≤ n ≤ 2 × 105,1 ≤ m ≤ 4 × 105,1 ≤ w ≤ 1 × 109,存在至少一条从 起点到终点的最短路。

    样例:

    8 9
    1 2 3 4 5 6 7 8
    1 2 2
    2 3 3
    3 8 3
    1 4 3
    4 5 2
    5 8 1
    1 6 1
    6 7 2
    7 8 3

    6
    1 4 5 8


    我们来看看这道。

    首先,求最短路和路径是不用说的,但是我们要字典序最小的最短路怎么办呢?

    那么我们为什么不在每次确定前驱节点的时候选出字典序最小的呢?

    那么,为了保证字典序最小,我们应该从终点开始反向走向起点(反向建边),然后当几个点同时是某点的前驱节点时,我们选出最小的,就可以解答了。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    #define il inline
    #define db double
    using namespace std;
    il int gi()
    {
        int x=0,y=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
            y=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*y;
    }
    il ll gl()
    {
        ll x=0,y=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
            y=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*y;
    }
    ll point[4000045];
    int head[16000045],cnt;
    struct edge
    {
        int next,to;
        ll lon;
    }e[16000045];
    il void add(int from,int to,ll lon)
    {
        e[++cnt].next=head[from];
        e[cnt].to=to;
        e[cnt].lon=lon;
        head[from]=cnt;
    }
    int t[16000045],headd,tail=1,n;
    ll dist[4000045];
    int pre[4000045];
    bool vis[4000045];
    il void spfa()
    {
        for(int i=1;i<=n;i++)
        dist[i]=1e16;
        point[0]=1e16;
        t[0]=n;
        dist[n]=0;
        while(headd!=tail)
        {
            int now=t[headd++];
            vis[now]=0;
            int r=head[now];
            while(r!=-1)
            {
                if(point[pre[e[r].to]]>point[now]&&dist[e[r].to]==dist[now]+e[r].lon)
                        pre[e[r].to]=now;
                if(dist[now]+e[r].lon<dist[e[r].to])
                {
                    dist[e[r].to]=dist[now]+e[r].lon;
                    pre[e[r].to]=now;
                    if(!vis[e[r].to])
                    {
                        vis[e[r].to]=1;
                        t[tail++]=e[r].to;
                    }
                }
                r=e[r].next;
            }
        }
    }
    int que[100045];
    int main()
    {
        freopen("journalist.in","r",stdin);
        freopen("journalist.out","w",stdout);
        memset(head,-1,sizeof(head));
        n=gi();
        int m=gi(),x,y;
        ll z;
        for(int i=1;i<=n;i++)
        point[i]=gi();
        for(int i=1;i<=m;i++)
        {
            x=gi(),y=gi(),z=gl();
            add(y,x,z);
        }
        spfa();
        printf("%lld
    ",dist[1]);
        for(int i=1;i!=0;i=pre[i])
        printf("%lld ",point[i]);
        return 0;
    }
    PEACE
  • 相关阅读:
    MySQL主从半同步复制
    MySQL主从之延时复制
    MySQL备份
    MySQL主从介绍及搭建(异步复制)
    MySQL物理备份Xtrabackup
    MySQL数据库误删除数据恢复
    MySQL--日志
    JAVA日报
    JAVA日报
    JAVA日报
  • 原文地址:https://www.cnblogs.com/gshdyjz/p/7405255.html
Copyright © 2020-2023  润新知