sub2 WA了四个,sub4 WA了三个。
欢迎指正或Hack。
思路是从终点开始跑Dijkstra,同时记录当前经过了几条边(也就是魔力值k),然后再用当前k更新边权,最后到起点的距离也就是最小生命值。
//2023/8/6
//别着急,先通读一遍题目
//别忘了开long long
//写完先看一遍怎么降复杂度
//要么开全局变量要么给定初值
//想想看,有什么情况需要特判
//看看数组开的够不够大
//std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=1e6+10;
const int INF=LLONG_MAX;
int num,ans;
int n,m,s,t;
struct node{
int id,stp;
int dist;
node(){ id=0;dist=0;stp=0;}
node(int c,int d,int e){id=c;dist=d;stp=e;}
bool operator < (const node &x)const{return x.dist<dist;}
};
priority_queue<node> que;
struct linkstar{
int to,from;
int w;
int next;
}edge[2*MAXN];
int head[MAXN],dis[MAXN],vis[MAXN];
int escnt;
void add(int from,int to,int w)
{
edge[++escnt].from=from;
edge[escnt].to=to;
edge[escnt].w=w;
edge[escnt].next=head[from];
head[from]=escnt;
}
void Dijkstra(int u)
{
for (int i=1;i<=n;i++) dis[i]=INF;
dis[u]=0;
que.push(node(u,0,1));
int cnt=0;
while(que.size()){
node cp=que.top();
que.pop();
if(vis[cp.id]) continue;
vis[cp.id]=1;
for (int i=head[cp.id];i!=-1;i=edge[i].next){
if(dis[edge[i].to]>dis[cp.id]+edge[i].w/cp.stp){
dis[edge[i].to]=dis[cp.id]+edge[i].w/cp.stp;
if(!vis[edge[i].to]) que.push(node(edge[i].to,dis[edge[i].to],cp.stp+1));
}
}
}
}
signed main()
{
memset(head,-1,sizeof(head));
cin>>n>>m>>s>>t;
int u,v,w;
for (int i=1;i<=m;i++){
cin>>u>>v>>w;
add(u,v,w);
add(v,u,w);
}
Dijkstra(t);
cout<<dis[s]<<endl;
return 0;
}