ABC340D 题解
题意
游戏有
思路
本题考查图论建模和最短路。
由于
则对于前
之后用最短路算法跑单源最短路即可,Dijkstra算法可过。
代码
#include<iostream>
#include<vector>
#include<queue>
#define int long long
#define pii pair<int,int>
using namespace std;
const int N=2e5+10;
const int maxs=1e15;
int read()
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-') w=-1; if(ch==EOF) return 0; ch=getchar();}
while(ch>='0'&&ch<='9'){ s=s*10+ch-'0'; ch=getchar();}
return s*w;
}
int n;
struct edg
{
int v,w;
};
vector <edg> edge[N];//邻接表存边
void add(int u,int v,int w)
{
edg t;
t.v=v;
t.w=w;
edge[u].push_back(t);
}//加有向边
int s[N];//最短路长度
bool v[N];//是否已经计算完最短路
priority_queue <pii > q;//注意为大根堆,且按pair的first排序
signed main()
{
n=read();
for(int i=1;i<n;i++)
{
int a=read(),b=read(),x=read();
add(i,i+1,a);
add(i,x,b);//加边
}
for(int i=1;i<=n;i++)
s[i]=maxs,v[i]=0;
s[1]=0;
q.push({0,1});//Dijkstra初始化
while(!q.empty())
{
int u=q.top().second;
q.pop();
if(v[u])
continue;
v[u]=1;
for(int i=0;i<edge[u].size();i++)
{
int ne=edge[u][i].v,tw=edge[u][i].w;
if(s[ne]>s[u]+tw)
{
s[ne]=s[u]+tw;
if(!v[ne])
q.push({-s[ne],ne});//取负,把大根堆用作小根堆
}
}
}//Dijkstra
cout<<s[n];
return 0;
}