最短路,注意理解题意;
只要一个戒备点次数增加,所有的戒备点次数都增加;
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int inf=1e18;
const int maxn=6000;
int head[maxn],cnt,dis[maxn],n,m,k,a[maxn],vis[maxn];
struct edge{
int nx,to,w;
}edge[maxn*maxn];
struct node{
int u,d,f;//f记录上一次戒备次数
friend bool operator < (const node &a,const node &b){
return a.d>b.d;
}
};
void add(int u,int v,int w)
{
edge[++cnt].nx=head[u];
edge[cnt].to=v;
edge[cnt].w=w;
head[u]=cnt;
}
void dij()
{
priority_queue<node> q;
q.push({1,0,0});
dis[1]=0;
while(!q.empty())
{
node t=q.top();q.pop();
int u=t.u,h=t.f;
int r=0;
if(a[u]) r=1;//判断当前戒备,因为是从一个戒备点到达任意一点时,戒备次数才增加
for(int i=head[u];i;i=edge[i].nx)
{
int v=edge[i].to,w=edge[i].w;
if(t.f+r<=k&&(dis[v]>dis[u]+w))
{
dis[v]=dis[u]+w;
q.push({v,dis[v],t.f+r});
}
}
}
return;
}
signed main()
{
scanf("%lld%lld%lld",&n,&m,&k);
for(int i=0;i<=n;i++) dis[i]=inf;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=m;i++)
{
int u,v,w;
cin>>u>>v>>w;
add(u,v,w),add(v,u,w);
}
dij();
if(dis[n]>=inf) cout<<-1<<endl;
else cout<<dis[n];
}
京公网安备 11010502036488号