带优先队列的dijkstra
#include <stdio.h>
#include <string.h>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
inline int input(){
int ret=0;
char c=getchar();
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9'){
ret=ret*10+c-'0';
c=getchar();
}
return ret;
}
#define N 100005
#define INF ~0U>>2
vector<int>K[N];
vector<pair<int,int> >edge[N];
int d[N];
struct node{
int w;
int val;
node(int _w,int _val):w(_w),val(_val){}
};
bool operator < (node i,node j){
return i.val>j.val;
}
priority_queue<node>q;
inline int search(vector<int>k,int val){
int s=0,t=k.size()-1;
while(s<=t){
int mid=(s+t)>>1;
if(k[mid]==val) return mid;
else if(k[mid]<val) s=mid+1;
else t=mid-1;
}
return -1;
}
int n,m,a,b,c,k;
bool vis[N];
int main(){
//scanf("%d%d",&n,&m);
n=input(),m=input();
d[1]=0;
for(int i=2;i<=n;i++) d[i]=INF;
memset(vis,0,sizeof(vis));
while(m--){
a=input(),b=input(),c=input();
edge[a].push_back(make_pair(b,c));
edge[b].push_back(make_pair(a,c));
}
for(int i=1;i<=n;i++){
k=input();
while(k--){
a=input();
K[i].push_back(a);
}
}
q.push(node(1,0));
while(!q.empty()){
int x=q.top().w;
q.pop();
if(vis[x]==1) continue;
vis[x]=1;
int pp=d[x];
if(K[x].size()>0){
int r=search(K[x],pp);
if(r!=-1){
pp++;
r++;
while(r<K[x].size() && pp==K[x][r]){//可能在你前面那人走的同时,又来了人...然后就是不要每次都是二分..
r++,pp++;
}
}
}
for(int i=0;i<edge[x].size();i++){
int nxt=edge[x][i].first;
int val=edge[x][i].second;
int p=pp+val;
if(p<d[nxt]){
d[nxt]=p;
q.push(node(nxt,p));
}
}
}
if(d[n]==INF) puts("-1");
else printf("%d\n",d[n]);
}