poj 1062(有限制的最短路)
题目链接:http://poj.org/problem?id=1062
思路:要求对于最短路上的点,不能出现等级之差大于m,于是我们可以枚举,假设酋长的等级为level,于是这个区间范围[level-m,level],[level-m+i,level+i],......,[level,level+m]都是可行的,对于枚举的每个区间范围,做一次SPFA即可,最终结果取最小值即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 #define MAXN 111 8 #define inf 1<<30 9 10 int value[MAXN],level[MAXN]; 11 int map[MAXN][MAXN]; 12 bool vis[MAXN],mark[MAXN]; 13 int dist[MAXN]; 14 int n,m,x; 15 16 int SPFA() 17 { 18 memset(vis,false,sizeof(vis)); 19 for(int i=1;i<=n;i++)dist[i]=inf; 20 dist[1]=0; 21 queue<int>Q; 22 Q.push(1); 23 while(!Q.empty()){ 24 int u=Q.front(); 25 Q.pop(); 26 vis[u]=false; 27 for(int v=1;v<=n;v++){ 28 if(map[u][v]&&mark[v]&&dist[u]+map[u][v]<dist[v]){ 29 dist[v]=dist[u]+map[u][v]; 30 if(!vis[v]){ Q.push(v);vis[v]=true; } 31 } 32 } 33 } 34 int ans=inf; 35 for(int i=1;i<=n;i++){ 36 dist[i]+=value[i]; 37 ans=min(ans,dist[i]); 38 } 39 return ans; 40 } 41 42 int main() 43 { 44 int id,val,MIN; 45 while(~scanf("%d%d",&m,&n)){ 46 memset(map,0,sizeof(map)); 47 for(int i=1;i<=n;i++){ 48 scanf("%d%d%d",&value[i],&level[i],&x); 49 while(x--){ 50 scanf("%d%d",&id,&val); 51 map[i][id]=val; 52 } 53 } 54 MIN=inf; 55 for(int i=0;i<=m;i++){ 56 memset(mark,false,sizeof(mark)); 57 for(int j=1;j<=n;j++){ 58 if(level[j]>=level[1]-m+i&&level[j]<=level[1]+i) 59 mark[j]=true; 60 } 61 MIN=min(MIN,SPFA()); 62 } 63 printf("%d\n",MIN); 64 } 65 return 0; 66 } 67 68 69 70 71