最短路的题,与一般的最短路不同的是,建图后每个结点有一个等级值(一个非负整数),要求最短路并且路线上的结点的最大等级差不超过给定值。
这题一开始我想到的就是枚举等级区间,在对应区间内用dijkstra求最短路,复杂度是L*N2,L是给定的最大等级差,N为结点数,由于题中L的最大值没有给出,所以我担心会超时,写好后提交是WA而不是TLE,这也让我确定了此法的可行性。经检查发现导致WA的错误:
1.建图错误,按题意应建有限图;
2.有一个两重循环的下标重复了;
3.松弛的时候忘了检查结点等级。
1 #include <stdio.h> 2 #include <string.h> 3 #define MAX(a,b) ((a)>(b)?(a):(b)) 4 #define MIN(a,b) ((a)<(b)?(a):(b)) 5 #define INF 0x7fffffff 6 #define N 101 7 int g[N][N],dist[N],val[N],rank[N],n,m; 8 char vis[N]; 9 void dijkstra(int u,int s) 10 { 11 int v,i,min,k; 12 memset(vis,0,sizeof(vis)); 13 for(i=0;i<n;i++) dist[i]=(i==u?0:INF); 14 for(i=0;i<n;i++) 15 { 16 min=INF; 17 for(v=0;v<n;v++) 18 { 19 if(!vis[v]&&dist[v]<=min&&rank[v]>=s&&rank[v]<=s+m) min=dist[k=v]; 20 } 21 vis[k]=1; 22 if(min==INF) break; 23 for(v=0;v<n;v++) 24 { 25 if(rank[v]>=s&&rank[v]<=s+m&&g[k][v]!=INF&&dist[v]>=dist[k]+g[k][v]) dist[v]=dist[k]+g[k][v]; 26 } 27 } 28 } 29 int main() 30 { 31 int i,j,k,a,b,s,tmp,ans; 32 while(~scanf("%d%d",&m,&n)) 33 { 34 for(i=0;i<n;i++) 35 { 36 for(j=i+1;j<n;j++) g[i][j]=g[j][i]=INF; 37 } 38 for(i=0;i<n;i++) 39 { 40 scanf("%d%d%d",&val[i],&rank[i],&k); 41 for(j=0;j<k;j++) 42 { 43 scanf("%d%d",&a,&b),a--; 44 g[i][a]=MIN(g[i][a],b); 45 } 46 } 47 ans=INF; 48 s=MAX(rank[0]-m,0); 49 for(i=s;i<=rank[0];i++) 50 { 51 dijkstra(0,i); 52 tmp=val[0]; 53 for(j=1;j<n;j++) 54 { 55 if(dist[j]==INF) continue; 56 tmp=MIN(tmp,dist[j]+val[j]); 57 } 58 ans=MIN(ans,tmp); 59 } 60 printf("%d\n",ans); 61 } 62 return 0; 63 }