ccf 201712-4 行车路线(70分)

ccf 201712-4 行车路线

解题思路:

  首先Dijkstra是基于贪心算法的,即每一次作出的选择都具有贪心选择性。此题由于有“如果连续走小道,小明的疲劳值会快速增加,连续走s公里小明会增加s2的疲劳度。”这种情况,所以不能使用Dijkstra算法。

  这里使用Bellman-Ford算法

70分备份待修改:

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 int n,m;//n为路口的数量,m为道路的数量
 5 const int maxn = 500 + 5;
 6 const int maxm = 100000 + 5;
 7 const int INF = 1000000;//无穷大
 8 struct node{
 9     int ci,cj;
10     int type;
11     int cij;
12 }path[2*maxm];
13 
14 int Edge[maxn][maxn];//记录两个点之间路径的编号
15 int dist[maxn];//记录源点1到每一个节点的最短路
16 int pro[maxn];//记录每一个节点的前驱结点
17 
18 void bellman()
19 {
20     memset(dist,INF,sizeof(dist));
21     dist[1] = 0;
22     memset(pro,-1,sizeof(pro));
23     pro[1] = 0;//1没有前驱
24     for(int k=1;k<n;k++)///进行n-1次松弛操作
25     {
26         bool flag = false;
27         for(int i=0;i<2*m;i++)
28         {
29             if(path[i].type == 0)//大道
30             {
31                 if(dist[path[i].cj] > dist[path[i].ci]+path[i].cij)
32                 {
33                     dist[path[i].cj] = dist[path[i].ci]+path[i].cij;
34                     pro[path[i].cj] = path[i].ci;
35                     flag = true;
36                 }
37              } else{//小道
38              //首先要计算出连续走小路多长时间
39                 int con = path[i].cij;
40                 int temp = i;
41                  if(pro[path[i].ci] != -1 && pro[path[i].ci] != 0)//已经加入,有前驱
42                  {
43 
44                      int pathnum = Edge[pro[path[temp].ci]][path[temp].ci];
45                      while( path[pathnum].type == 1)//连续走小道
46                      {
47                          con += path[pathnum].cij;
48                          temp = Edge[pro[path[temp].ci]][path[temp].ci];
49                          if(pro[path[pathnum].ci] == 0) break;//到达起始结点
50                          pathnum = Edge[pro[path[temp].ci]][path[temp].ci];
51                       }
52 
53                   }
54                  if(dist[path[i].cj]>dist[path[temp].ci] + con*con)
55                  {
56                      dist[path[i].cj]=dist[path[temp].ci] + con*con;
57                      pro[path[i].cj] = path[i].ci;
58                     flag = true;
59                  }
60              }
61         }
62         if(!flag) break;
63      }
64 }
65 
66 int main()
67 {
68 
69     while(cin>>n>>m)
70     {
71         for(int i=0;i<2*m;i++)
72         {
73             cin>>path[i].type>>path[i].ci>>path[i].cj>>path[i].cij;
74             i++;
75             path[i].ci = path[i-1].cj;path[i].cj = path[i-1].ci;
76             path[i].cij = path[i-1].cij;path[i].type = path[i-1].type;
77             Edge[path[i].ci][path[i].cj] = i;
78             Edge[path[i].cj][path[i].ci] = i-1;
79         }
80 
81         bellman();
82         cout<<dist[n]<<endl;
83     }
84     return 0;
85  }

原文地址:https://www.cnblogs.com/yxh-amysear/p/8495296.html