您的位置:首页 > 其它

JZOJ5279. 【NOIP提高组模拟A组8.15】香港记者

2017-08-15 20:14 399 查看




分析

第一问显然就是最短路,

关键是如何解决第二问。

这个不是单纯的要求输出路径,

而是要求路径的最小字典序。

我们不可能将到达每一个点的最小字典序的全部保留下来,

那如果判断当前字典序。

每次找字典序最小的走,是错误的。

考虑字典序是如果比较的,是逐位比较的,

也就是如果两个数,位于序列中相同的位置,

那我们就可以直接比较大小。

但是,如果我们从1开始spfa是无法满足相同的位置,

那就换种思路,

将所以边反过来,从n开始spfa。

我们知道从1到一个点的最优答案是位于的,

当我们从n出发,有两个点都可以更新一个点,

那我们就可以将它们两个直接比较大小。

最后我们从1开始,统计一下路径就可以了。

code

#include<queue>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#define ll long long
#define N 200003
#define db double
#define P putchar
#define G getchar
#define mo 1000000007
using namespace std;
char ch;
void read(int &n)
{
n=0;
ch=G();
while((ch<'0' || ch>'9') && ch!='-')ch=G();
ll w=1;
if(ch=='-')w=-1,ch=G();
while('0'<=ch && ch<='9')n=n*10+ch-'0',ch=G();
n*=w;
}

void write(int x)
{
if(x>9) write(x/10);
P(x%10+'0');
}

int next[N*2],a[N*2],v[N*2],last
,tot;
int n,m,b
,x,y,z,f
,d[N*100];
ll dis
;
bool bz
;

void ins(int x,int y,int z)
{
next[++tot]=last[x];
a[tot]=y;
v[tot]=z;
last[x]=tot;
}

int main()
{
read(n);read(m);
for(int i=1;i<=n;i++)
read(b[i]);
for(int i=1;i<=m;i++)
read(x),read(y),read(z),ins(y,x,z);

memset(dis,127,sizeof(dis));
memset(bz,1,sizeof(bz));
bz
=dis
=0;
d[1]=n;
int head=0,tail=1;

while(head<tail)
{
x=d[++head];
for(int i=last[x];i;i=next[i])
if(dis[a[i]]>dis[x]+v[i] || (dis[a[i]]==dis[x]+v[i] && b[f[a[i]]]>b[x]))
{
dis[a[i]]=dis[x]+v[i];
f[a[i]]=x;
if(bz[a[i]])
{
bz[a[i]]=0;
d[++tail]=a[i];
}
}
bz[x]=1;
}

printf("%lld\n",dis[1]);
x=1;y=0;
while(x)
{
write(b[x]),P(' ');
x=f[x];
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  单源最短路