Every day you drive to work using the same roads as it is the shortest way. This is efficient, but over time you have grown increasingly bored of seeing the same buildings and junctions every day. So you decide to look for different routes. Of course you do not want to sacrifice time, so the new way should be as short as the old one. Is there another way that differs from the old one in at least one street?
Input Format
The first line of the input starts with three integers NN MM and KK, where NN is the number of junctions and MM is the number of streets in your city, and KK is the number of junctions you pass everyday (1 \le K \le N \le 10000, 0 \le M \le 1000000)(1≤K≤N≤10000,0≤M≤1000000).
The next line contains KK integers, the (11-based) indices of the junctions you pass every day. The first integer in this line will always be 11, the last integer will always be NN. There is a shortest path from 11 to NN along the KKjunctions given.
MM lines follow. The ii-th of those lines contains three integers a_iai b_ibi c_ici and describes a street from junction a_iai to junction b_ibi of length c_ici (1 \le a_i,b_i \le N, 1 \le c_i \le 10000)(1≤ai,bi≤N,1≤ci≤10000). Streets are always undirected.
Note that there may be multiple streets connecting the same pair of junctions. The shortest path given uses for every pair of successive junctions aa and bb a street of minimal length between aa and bb.
Output Format
Print one line of output containing "yes"
if there is another way you can take without losing time, "no"
otherwise.
样例输入1
3 3 3 1 2 3 1 2 1 2 3 2 1 3 3
样例输出1
yes
样例输入2
4 5 2 1 4 1 2 2 2 4 1 1 3 1 3 4 2 1 4 2
样例输出2
no
代码:
#include<bits/stdc++.h>
using namespace std;
const int N =1e4+5;
const int M =2010000;
const int inf =0x3f3f3f3f;
const int mod=1e9+7;
typedef pair<int,int > pii;
struct node
{
int to;
int next;
int w;
}edge[M];
int head[N],tot;
void init()
{
memset(head,-1,sizeof(head));
tot=0;
}
void add(int u,int v,int w)
{
edge[++tot].to=v; edge[tot].w=w; edge[tot].next=head[u]; head[u]=tot;
return ;
}
int dis[N];
bool vis[N];
int pcnt[N];
int n,m,k;
priority_queue<pii,vector<pii>, greater<pii> >q;
void dij()
{
for(int i=0;i<=n;i++){
dis[i]=inf; vis[i]=0; pcnt[i]=0;
}
dis[1]=0; vis[1]=1; pcnt[1]=1;
while(!q.empty()) q.pop();
q.push(pii(0,1));
int u,v,w;
pii tmp;
int val;
while(!q.empty()){
tmp=q.top(); q.pop();
u=tmp.second;
if(tmp.first>dis[u]) continue;
vis[u]=1;
for(int i=head[u];i!=-1;i=edge[i].next){
v=edge[i].to;
val=edge[i].w;
//if(vis[v]) continue; //因为要判断相等的情况,所以这里不能判断是否访问过。
if(dis[v]>dis[u]+val){
dis[v]=dis[u]+val;
pcnt[v]=pcnt[u];
q.push(make_pair(dis[v],v));
}
else if(dis[v]==dis[u]+val){
pcnt[v]=(pcnt[v]+pcnt[u])%mod;
//q.push(make_pair(dis[v],v)); 这里加上的话就会超内存。 增加无用的操作,但使得堆变大。
}
}
}
if(pcnt[n]>1){
cout<<"yes"<<endl;
return ;
}
cout<<"no"<<endl;
return ;
}
int main()
{
scanf("%d %d %d",&n,&m,&k);
int x;
for(int i=1;i<=k;i++) scanf("%d",&x);
int u,v,w;
init();
for(int i=1;i<=m;i++){
scanf("%d %d %d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
dij();
return 0;
}