生命
给定一张图,有 \(n\) 个点 \(m\) 条双向边组成,DD 目前在 \(1\) 号点上要到 \(n\) 号点去,这 \(n\) 个点中有一些点上有机器人,机器人和 DD 的速度都是每秒可以走一个单位长度,这些机器人都是 AI 操控采取最优策略来拦截 DD,DD 每碰到一个机器人就会扣一滴生命值(一个点上碰到 \(x\) 个就扣 \(x\) 滴生命值),她想知道从 \(1\) 号点到 \(n\) 号点最少要扣多少生命值。
输入格式
第一行两个整数分别表示 \(n,m\)
第二行 \(n\) 个整数,\(a_i\)表示 \(i\) 号点上有 \(a_i\)个机器人
接下来 \(m\) 行,每行三个整数,分别表示该边的起点、终点和长度
输出格式
输出最少要扣多少生命值
数据范围
对于 \(30\%\) 的数据,\(2 \leq n \leq 10, 1 \leq m \leq 20\)
对于 \(50\%\) 的数据, \(2 \leq n \leq 500, 1 \leq m \leq 1000\)
对于\(100\%\)的数据,\(1 \leq u_i,v_i \leq n, 2 \leq n \leq 10^5,1 \leq m \leq 5*10^5,1 \leq dis_i,a_i \leq 10^9\)
输出时每行末尾的多余空格,不影响答案正确性
样例输入
4 6
1 2 3 4
1 2 1
2 3 2
3 4 1
1 4 2
2 4 10
4 4 3
样例输出
8
首先如果一个机器人在中途跟上了他,那么机器人可以一路跟到终点再杀他。因为和DD速度相同,所以他们的最优策略均是直奔终点。
那么方法就很明确了。求出从1号点到n号点的最短路和n号点到其他点的最短路,然后如果有机器人的最短路小于等于DD的最短路,那么DD逃不过这些机器人的伤害
#include
using namespace std;
const int N=1e5+5,M=5e5+5;
struct node{
int v;
long long w;
bool operator<(const node&n)const{
return w>n.w;
}
};
int n,m,k;
vectorg[N];
long long p;
int a[N];
long long dis[N];
priority_queuepq;
bool vis[N];
long long ans;
void dijkstra(int s)
{
pq.push((node){s,0});
dis[s]=0;
while(!pq.empty())
{
k=pq.top().v;
pq.pop();
if(vis[k])
continue;
vis[k]=1;
for(int i=0;i>n>>m;
for(int i=1;i<=n;i++)
scanf("%lld",a+i);
for(int i=1;i<=m;i++)
{
scanf("%d%d%lld",&u,&v,&w);
g[u].push_back((node){v,w});
g[v].push_back((node){u,w});
}
memset(dis,1,sizeof(dis));
dijkstra(1);
p=dis[n];
memset(dis,1,sizeof(dis));
memset(vis,0,sizeof(vis));
dijkstra(n);
for(int i=1;i<=n;i++)
if(dis[i]<=p)
ans+=a[i];
cout<