题目描述
A国有N座城市,依次标为1到N。同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数。现在,A国交通部指定了一条从城市1到城市N的路径,并且保证这条路径的长度是所有从城市1到城市N的路径中最短的。不幸的是,因为从城市1到城市N旅行的人越来越多,这条由交通部指定的路径经常发生堵塞。现在A国想知道,这条路径中的任意一条道路无法通行时,由城市1到N的最短路径长度是多少。
输入输出格式
输入格式:
输入文件第一行是三个用空格分开的正整数N、M和L,分别表示城市数目、单向道路数目和交通部指定的最短路径包含多少条道路。按下来M行,每行三个用空格分开的整数a、b和c,表示存在一条由城市a到城市b的长度为c的单向道路。这M行的行号也是对应道路的编号,即其中第1行对应的道路编号为1,第2行对应的道路编号为2,...,第M行对应的道路编号为M。最后一行为L个用空格分开的整数sp(1)...,,sp(L),依次表示从城市1到城市N的由交通部指定的最短路径上的道路的编号。
输出格式:
输出文件包含L行,每行为一个整数,第i行(i=1,2...,,L)的整数表示删去编号为sp(i)的道路后从城市1到城市N的最短路径长度。如果去掉后没有从城市1到城市N的路径,则输出一1。
输入输出样例
说明
100%的数据满足2<N<100000,1<M<200000。所用道路长度大于0小于10000。
数据已加强By Vfleaking
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int gg=1e5+29; 4 inline void read(int &x){ 5 int f=1;x=0;char c=getchar(); 6 while(!isdigit(c)){ 7 if(c==‘-‘)f=-1; 8 c=getchar(); 9 } 10 while(isdigit(c)){ 11 x=(x<<3)+(x<<1)+c-‘0‘; 12 c=getchar(); 13 } 14 x*=f; 15 } 16 struct node{ 17 int net; 18 int to; 19 int w; 20 }a[gg<<1]; 21 struct noded{ 22 int id,d; 23 bool operator <(const noded &b) const { 24 return d>b.d; 25 } 26 }; 27 int cnt; 28 int head[gg],dis[gg],sum[gg],pos[gg],to[gg],fro[gg],ro[gg]; 29 bool vis[gg],ban[gg<<1]; 30 int n,m,l; 31 priority_queue<noded>s; 32 deque<int>q; 33 inline void add(int i,int j,int w) 34 { 35 a[++cnt].to=j; 36 a[cnt].net=head[i]; 37 a[cnt].w=w; 38 head[i]=cnt; 39 } 40 inline void spfa(int qwq) 41 { 42 q.push_back(qwq); 43 while(!q.empty()) 44 { 45 int u=q.front(); 46 q.pop_front(); 47 vis[u]=false; 48 for(register int i=head[u];i;i=a[i].net) 49 { 50 if(ban[i]) 51 continue; 52 int v=a[i].to; 53 if(dis[u]+a[i].w>=dis[v]) 54 continue; 55 if(dis[v]>a[i].w+dis[u]) 56 dis[v]=a[i].w+dis[u]; 57 if(pos[v]) 58 s.push((noded){pos[v],dis[v]+sum[pos[v]]}); 59 else 60 { 61 if(!vis[v]) 62 { 63 vis[v]=true; 64 if(q.empty()||dis[v]>dis[q.front()]) 65 { 66 q.push_back(v); 67 } 68 else 69 { 70 q.push_front(v); 71 } 72 } 73 } 74 } 75 } 76 } 77 int main() 78 { 79 memset(dis,0x7f,sizeof(dis)); 80 memset(vis,false,sizeof(vis)); 81 dis[1]=0; 82 read(n),read(m),read(l); 83 for(register int i=1;i<=m;i++) 84 { 85 int x,y,z; 86 read(x),read(y),read(z); 87 add(x,y,z); 88 } 89 fro[1]=1; 90 pos[1]=1; 91 for(register int i=1;i<=l;i++) 92 { 93 read(ro[i]); 94 ban[ro[i]]=true; 95 fro[i+1]=a[ro[i]].to; 96 pos[fro[i+1]]=i+1; 97 } 98 for(register int i=l;i;i--) 99 sum[i]=sum[i+1]+a[ro[i]].w; 100 spfa(1) ; 101 for(register int i=1;i<=l;i++) 102 { 103 while(!s.empty()&&s.top().id<=i) 104 s.pop(); 105 if(s.empty()) 106 cout<<-1<<endl; 107 else 108 printf("%d\n",s.top().d); 109 dis[a[ro[i]].to]=dis[fro[i]]+a[ro[i]].w; 110 spfa(fro[i+1]); 111 } 112 return 0; 113 }