标签:
题意:其实吧,,我也没看懂题意。。还是说一下dijkstra算法,,三个步骤,循环n次
while(n--)
{
在所有未标号节点中,选出d[]值最小的节点
标记
松弛所有与这个点相关的所有边
}
这个算法的精髓在于,每次找到的最小边都不能被其他节点松弛,只能它去松弛别的节点。这样,就可以打印出来最短路径的遍历顺序了;换种说法就是,每次找到的那个点,都是最有资格去松弛其他节点的点,所以最多循环n次;不可以处理负环
Bellman 的算法:
循环n-1次,每次将所有的边松弛一遍;这个算法可以检查是否有负环,当出现负环/正环的时候,还可以继续松弛。
AC代码:
1 //dijkstla算法 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 #define INF 0x3f3f3f3f 6 using namespace std; 7 int vis[105],edge[105][105],n,price[105],level[105],d[105]; 8 void init() 9 { 10 for(int i=1; i<=n; i++) 11 { 12 for(int j=1; j<=n; j++) 13 { 14 edge[i][j]=INF;//初始化,要求最短路径,所以先初始化为无穷大 15 } 16 } 17 } 18 void read() 19 { 20 int l,t,tp; 21 for(int i=1; i<=n; i++) 22 { 23 scanf("%d%d%d",&price[i],&level[i],&l); 24 for(int j=0; j<l; j++) 25 { 26 scanf("%d%d",&t,&tp); 27 edge[t][i]=tp;//存储边的信息的时候,要将能到达的”优惠价格“存起来 28 } 29 } 30 } 31 int dijkstla()//算法主要分三个步骤,循环n次。1.找出所有节点中最小的2.标记3.松弛所有的与这个节点相关的点。 32 { 33 for(int i=1; i<=n; i++) 34 { 35 d[i]=price[i]; 36 } 37 int pos; 38 for(int i=1; i<=n; i++) 39 { 40 int temp=INF; 41 for(int j=1; j<=n; j++) 42 { 43 if(d[j]<temp&&!vis[j]) 44 { 45 temp=d[j]; 46 pos=j; 47 } 48 } 49 vis[pos]=1; 50 for(int j=1; j<=n; j++) 51 { 52 if(d[j]>d[pos]+edge[pos][j]&&!vis[j]) 53 { 54 d[j]=d[pos]+edge[pos][j]; 55 } 56 } 57 } 58 return d[1]; 59 } 60 int main() 61 { 62 int m,ans; 63 while(~scanf("%d%d",&m,&n)) 64 { 65 init(); 66 read(); 67 ans=INF; 68 for(int i=1; i<=n; i++) 69 { 70 int min1=level[i]; 71 for(int j=1; j<=n; j++) 72 { 73 if(level[j]<min1||level[j]-min1>m) 74 { 75 vis[j]=1; 76 } 77 else 78 { 79 vis[j]=0; 80 } 81 } 82 int now=dijkstla(); 83 ans=min(ans,now); 84 } 85 printf("%d\n",ans); 86 } 87 return 0; 88 }
标签:
原文地址:http://www.cnblogs.com/qioalu/p/4709176.html