AT_abc271_e

前言

第一眼看到这道题的时候以为是个图论,可是发现老师放在 Dp 题单中的,便立即转变思路,然后一下就出来了。

思路

我们可以定义 \(f_i\) 为从 \(1\) 号点走到 \(i\) 号点是否可以,那么我们的转移只需要将互相能到达的两个点的路径相互转移一下即可,这里的转移方程为 \(f_i=f_j+z\) 这里的 \(j\)\(i\) 能到达的点,\(z\) 为边权。

代码

#include <bits/stdc++.h>
#define IOS std::ios::sync_with_stdio(fasle);cin.tie(NULL);cout.tie(NULL)
#define int long long
#define ri register int
#define rep(i,x,y) for(ri i=x;i<=y;i++)
#define rep1(i,x,y) for(ri i=x;i>=y;i--)
#define il inline
#define fire signed
#define pai(a,x,y) sort(a+x,a+y+1)
using namespace std ;
il int qmi(int a,int b) {
	int res=1;
	while(b) {
		if(b&1) res=(res*a);
		a=a*a;
		b>>=1;
	}
	return res;
}
void print(int x) {
	if(x>=10) print(x/10);
	putchar(x%10+'0');
}
#define gcd(x,y) __gcd(x,y)
#define lcm(x,y) x*y/gcd(x,y)
const int N=2e5+10;
struct node{
	int x,y,z;
}edg[N];
int n,m,k,dis[N];
fire main() {
	cin>>n>>m>>k;
	rep(i,1,m) {
		int a,b,c;
		cin>>a>>b>>c;
		edg[i]={a,b,c};
	}
	rep(i,2,n) dis[i]=0x3f3f3f3f3f3f3f3f;
	rep(i,1,k) {
		int u;
		cin>>u;
		dis[edg[u].y]=min(dis[edg[u].y],dis[edg[u].x]+edg[u].z);
	}
	if(dis[n]>=0x3f3f3f3f3f3f3f3f) puts("-1");
	else cout<<dis[n]<<endl;
	return false;
}

posted @ 2024-01-31 11:48  highkj  阅读(5)  评论(0)    收藏  举报