题目大意:有向图,新计划的地铁,有k个计划新路,利用现有的铁路、k条新路和限定只能用d条新路,找出从0到n-1的最短路径
题目思路:用dist[u][use],储存使用use条新路,到达节点u的最短路径。
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<iostream> #include<algorithm> #include<vector> #include<queue> #define MAXSIZE 100005 #define INF 0x3f3f3f3f #define LL long long using namespace std; //题意:有向图,新计划的地铁,有k个计划新路,利用现有的铁路、k条新路和限定只能用d条新路,找出从0到n-1的最短路径 typedef pair<int,int>p; //p.firsr储存节点,p.second储存到达该节点使用的新路的数目 int k,a[MAXSIZE],dist[MAXSIZE][15]; struct node { int u; int v; int w; int op; int next; }G[MAXSIZE]; void Add(int u,int v,int w,int op) { G[k].u=u; G[k].v=v; G[k].w=w; G[k].op=op; G[k].next=a[u]; a[u]=k++; } void spfa(int n,int d) { queue<p> Q; dist[0][0]=0; Q.push(p(0,0)); while(!Q.empty()) { p k=Q.front(); Q.pop(); int u=k.first; int use=k.second; for(int i=a[u];i!=-1;i=G[i].next) { int v = G[i].v; int new_use = use + G[i].op; int new_d = dist[u][use] + G[i].w; if(dist[v][new_use] > new_d && new_use <= d) //更新使用new_use条新路到达v点的最短路 { dist[v][new_use] = new_d; Q.push(p(v,new_use)); } } } } void Init() { for(int i=0;i<MAXSIZE;i++) { a[i]=-1; for(int j=0;j<15;j++) dist[i][j]=INF; } k=1; } int main() { int T,n,m,b,d,cns=1; int u,v,w; scanf("%d",&T); while(T--) { Init(); scanf("%d%d%d%d",&n,&m,&b,&d); while(m--) { scanf("%d%d%d",&u,&v,&w); Add(u,v,w,0); //Add(v,u,w,0); } while(b--) { scanf("%d%d%d",&u,&v,&w); Add(u,v,w,1); // Add(v,u,w,1); } spfa(n,d); int ans=INF; for(int i=0;i<=d;i++) ans=min(ans,dist[n-1][i]); if(ans < INF) printf("Case %d: %d ",cns++,ans); else printf("Case %d: Impossible ",cns++); } return 0; }