香港记者

来源:互联网 发布:网络购物诈骗的定义 编辑:程序博客网 时间:2024/04/28 12:31

题目背景

众所周知,香港记者跑得比谁都快,这其中其实是有秘诀的。

首先他们会跑最短路,但是最短路会有很多条,而且其他记者也知道要跑最短路,香港记者还统计出了每座城市带黑框眼镜的人数,如果一个记者跑路的时候城市带黑框眼镜人数的序列字典序比另一个记者大,那么这个记者就会被不可描述的力量续走时间,导致他跑得没字典序小的记者快。

题目描述

长者日续万秒日理万机,想请你告诉他香港记者经过的总路程和城市带黑框眼镜人数的序列,方便他找到香港记者,传授他们一些人生经验。

方便起见,设起点为1 终点为n。

由于不可描述的力量,各个城市带黑框眼镜的人数各不相同。

输入输出格式

输入格式:

第一行,两个整数n;m 表示有n 个城市,城市之间有m 条有向边。

第二行,n 个数,表示每个城市带黑框眼镜的人数bi:

接下来m 行,每行3 个非负整数ui; vi;wi 表示一条有向边的起点,终点,路程。

输出格式:

第一行,一个非负整数表示香港记者经过的总路程。

第二行,若干个非负整数表示香港记者经过的城市带黑框眼镜人数的序列。

输入输出样例

输入样例#1:
8 91 2 3 4 5 6 7 81 2 22 3 33 8 31 4 34 5 25 8 11 6 16 7 27 8 3
输出样例#1:
61 4 5 8

说明

对于前30% 的数据,2<=n<=2 *10^3,1<=m<=4 * 10^3。

对于前60% 的数据,保证数据随机。

对于另外30% 的数据,保证所有起点到终点的简单路径(没有环的路径)长度相同。

对于100% 的数据,2<=n<=2*10^5,1<=m<=4*10^5,1<=w<=1*10^9,存在至少一条从起点到终点的最短路。


思路,倒着做最短路,保存每个点的前驱,在正图里就是每个点的后继,然后正着宽搜,每次把最小的加进队列,如果有多个就全都加入。

#include<bits/stdc++.h>#define f(i,l,r) for(i=(l);i<=(r);i++)using namespace std;const int MAXN=200005,MAXM=400005;int a[MAXN],head[MAXN],tot,vis[MAXN],tmp[MAXN][100],sz;long long d[MAXN];long long heap[2][MAXN<<1];struct Edge{    int v,next;    long long w;}e[MAXM];int n,m;template <typename T> void read(T &x) {    x = 0; char c = getchar();    for (; !isdigit(c); c = getchar());    for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';}inline void add(int u,int v,long long w){    e[++tot].v=v;    e[tot].w=w;    e[tot].next=head[u];    head[u]=tot;}inline void pushup(int p){    int fa=p>>1,a=heap[0][p],id=heap[1][p];    while(fa&&a<heap[0][fa]){        heap[0][p]=heap[0][fa];        heap[1][p]=heap[1][fa];        p=fa;        fa>>=1;    }    heap[0][p]=a;    heap[1][p]=id;}inline void pushdown(int p){    int son=p<<1,a=heap[0][p],id=heap[1][p];    while(son<=sz){        while(son<sz&&heap[0][son]>heap[0][son+1]){            son++;        }        if(a<=heap[0][son]) break;        heap[0][p]=heap[0][son];        heap[1][p]=heap[1][son];        p=son;        son<<=1;    }    heap[0][p]=a;    heap[1][p]=id;}inline void insert(int a,int id){    heap[0][++sz]=a;    heap[1][sz]=id;    pushup(sz);}inline void Pop(){    heap[0][1]=heap[0][sz];    heap[1][1]=heap[1][sz--];    if(sz) pushdown(1);}inline void Dijkstra(){    int i;//    memset(d,127,sizeof(d));    d[n]=1;    insert(1,n);    while(sz){        int u=heap[1][1];        Pop();        if(vis[u]) continue;        vis[u]=1;        for(i=head[u];i;i=e[i].next){            int v=e[i].v;            long long w=e[i].w;            if(!d[v]||d[v]>=d[u]+w){                if(!d[v]||d[v]>d[u]+w){                    d[v]=d[u]+w;                    tmp[v][0]=0;                    tmp[v][++tmp[v][0]]=u;                }                else{                    tmp[v][++tmp[v][0]]=u;                }                insert(d[v],v);            }        }    }}/*inline int dfs(int u){    int i;    if(u==n){        return 1;    }    for(i=head[u];i;i=e[i].next){        int v=e[i].v;        if(d[v]==d[u]+e[i].w){            if(path[v]==1||(!path[v]&&dfs(v)==1)){                path[u]=1;            }        }    }    if(path[u]!=1) path[u]=2;    return path[u];}*/inline void BFS(){    int u=1,i,MIN_c,pos;    printf("%d ",a[1]);    while(1){        MIN_c=2000000000;        f(i,1,tmp[u][0]){            if(MIN_c>a[tmp[u][i]]){                MIN_c=a[tmp[u][i]];                pos=tmp[u][i];            }            }        printf("%d ",MIN_c);        u=pos;        if(pos==n) return;    }    return;}int main(){//    freopen("journalist10.in","r",stdin);//    freopen("journalist100.out","w",stdout);    int i,j,u,v;    long long w;    scanf("%d%d",&n,&m);    f(i,1,n){        read(a[i]);    }    f(i,1,m){        read(u);read(v);read(w);        add(v,u,w);    }    Dijkstra();    printf("%lld\n",d[1]-1);    BFS();    return 0;}