【GOJ 2963】记者

解析

根据题目要求,我们要先求出最短路(正权图肯定用 dijkstra)。

我们 神奇地发现 每步走关于起点的最短路图的时候步步走标号最小的点有可能走不到终点。

于是我们在进行最短路时一起把最佳方案求了。

注意到 各个城市带黑框眼镜的人数各不相同,开 long long

代码

#include<bits/stdc++.h>
using LL=long long;
using namespace std;
namespace io {
	inline LL read() {
		LL x=0,f=1;
		char c=IO::getchar();
		while(c<'0'||c>'9') {
			if(c=='-') {
				f=-1,c=IO::getchar();
			}
		}
		while(c>='0'&&c<='9') {
			x=x*10+c-'0',c=IO::getchar();
		}
		return x*f;
	}
	inline void write(LL x) {
		char buf[200];
		if(!x) {
			IO::putchar( '0' );
			return ;
		}
		LL tmp=x>0?x:-x;
		if(x<0) {
			IO::putchar('-');
		}
		LL cnt=0 ;
		while(tmp>0) {
			buf[cnt++]=tmp%10+'0',tmp/=10;
		}
		while(cnt>0) {
			IO::putchar(buf[--cnt]);
		}
	}
}
using namespace io;
const LL N=2e5+5;
struct edge {
	LL to,w,nxt;
} e[(N<<1)-15];
LL n,tmp,head[N],vis[N],dis[N];
void add(LL x,LL y,LL z) {
	e[++tmp].to=y;
	e[tmp].w=z;
	e[tmp].nxt=head[x];
	head[x]=tmp;
}
priority_queue<pair<LL,LL>> q;
LL tag[N],b[N];
void dijkstra(LL u) {
	q.push(make_pair(0,u)),dis[u]=0;
	while(q.size()) {
		u=q.top().second,q.pop();
		if(vis[u]) {
			continue;
		}
		vis[u]=1;
		for(LL i=head[u],v,w; i; i=e[i].nxt) {
			v=e[i].to,w=e[i].w;
			if(vis[v]) {
				continue;
			}
			if(dis[u]+w<dis[v]) {
				tag[v]=u,dis[v]=dis[u]+w,q.push(make_pair(-dis[v],v));
			} else if(dis[u]+w==dis[v]) {
				if(b[u]<b[tag[v]]) {
					tag[v]=u;
				}
			}
		}
	}
}
int main() {
	n=read();
	LL m=read();
	for(LL i=1; i<=n; i++) {
		b[i]=read();
	}
	for(LL i=0,u,v,w; i<m; i++) {
		u=read(),v=read(),w=read(),add(v,u,w);
	}
	memset(dis,0x7f,sizeof(dis));
	dijkstra(n),write(dis[1]),IO::putchar('
');
	LL now=1;
	while(1) {
		write(b[now]),IO::putchar(' ');
		if(now==n) {
			break;
		}
		now=tag[now];
	}
	return 0;
}
原文地址:https://www.cnblogs.com/Sam2007/p/14322122.html