1003_Emergency (25分)[最短路]

题意:计算从城市C1到城市C2最短路有几条,并求取最短路的最多人数。

每次都想着DFS一下,果然还是超时了。

 1 #include<iostream>
 2 #include<vector>
 3 #include<map>
 4 #include<cmath>
 5 #include<cstdio>
 6 #include<cstdlib>
 7 #include<cstring>
 8 #include<algorithm>
 9 using namespace std;
10 
11 const int maxSize = 500 + 10;
12 int rescue[maxSize], road[maxSize][maxSize];
13 bool vis[maxSize];
14 int num, maxRescue, minRoad, tempRescue, tempRoad;
15 int N, M, C1, C2;
16 
17 void dfs(int s) {
18     if (s == C2) {
19         if (tempRoad < minRoad) {
20             num = 1;
21             minRoad = tempRoad;
22             maxRescue = tempRescue;
23         }
24         else if (tempRoad == minRoad) {
25             num++;
26             maxRescue = max(maxRescue, tempRoad);
27         }
28         return;
29     }
30     if (tempRoad > minRoad) return; //剪枝
31     for (int i = 0; i < N; i++) {
32         if (!vis[i]&&road[s][i]!=-1) {
33             vis[i] = 1;
34             tempRescue += rescue[i];
35             tempRoad += road[s][i];
36             dfs(i);
37             vis[i] = 0;
38             tempRescue -= rescue[i];
39             tempRoad -= road[s][i];    
40         }
41     }
42 }
43 
44 
45 int main()
46 {
47     while (cin >> N >> M >> C1 >> C2) {
48         num = 1; tempRescue = tempRoad = maxRescue = 0;
49         minRoad = 0xfffffff;
50         memset(rescue, 0, sizeof(rescue));
51         memset(road, -1, sizeof(road));
52         memset(vis, 0, sizeof(vis));
53         for (int i = 0; i < N; i++) cin >> rescue[i];
54         for (int i = 0; i < M; i++) {
55             int x, y, p;
56             cin >> x >> y >> p;
57             if (road[x][y] == -1) road[x][y] = road[y][x] = p;
58             else road[x][y] = road[y][x] = min(road[x][y], p);
59         }
60         vis[C1] = 1;
61         tempRescue += rescue[C1];
62         dfs(C1);
63         cout << num << " " << maxRescue << endl;
64     }
65     return 0;
66 }

基础 Dijkstra

 1 #include<iostream>
 2 #include<vector>
 3 #include<map>
 4 #include<set>
 5 #include<cmath>
 6 #include<cstdio>
 7 #include<cstdlib>
 8 #include<cstring>
 9 #include<algorithm>
10 using namespace std;
11 
12 const int maxSize = 500 + 10;
13 int num, maxRescue, tempRescue;
14 bool vis[maxSize];
15 int N, M, C1, C2, S;
16 int rescue[maxSize], dis[maxSize];
17 int rescueSum[maxSize], road[maxSize][maxSize];
18 
19 //dfs反向搜索
20 void dfs(vector<set<int>>& record,int x) {
21     if (x == C1) {
22         num++;
23         maxRescue = max(maxRescue, tempRescue);
24         return;
25     }
26     for (auto iter = record[x].begin(); iter != record[x].end(); iter++) {
27         tempRescue += rescue[*iter];
28         dfs(record, *iter);
29         tempRescue -= rescue[*iter];
30     }
31 }
32 
33 int main()
34 {
35     while (cin >> N >> M >> C1 >> C2) {
36         memset(road, -1, sizeof(road));
37         memset(vis, 0, sizeof(vis));
38         memset(dis, 0x7f, sizeof(dis));
39         memset(rescue, 0, sizeof(rescue));
40         memset(rescueSum, 0, sizeof(rescueSum));
41         for (int i = 0; i < N; i++) cin >> rescue[i];
42         for (int i = 0; i < M; i++) {
43             int x, y, p;
44             cin >> x >> y >> p;
45             if (road[x][y] == -1) road[x][y] = road[y][x] = p;
46             else road[x][y] = road[y][x] = min(road[x][y], p);
47         }
48         //Dijkstra查找最短路程以及记录路径
49         dis[C1] = 0; //起始点自身到自身为0
50         dis[N] = 0x7fffffff; //设置距离最大点
51         vector<set<int>> record(N); //反向记录
52         for (int i = 1; i < N; i++) {
53             //选最近点
54             if (i == 1) {
55                 S = C1;
56             }
57             else {
58                 S = N; //设置距离最大点
59                 for (int j = 0; j < N; j++) {
60                     if (!vis[j] && dis[j] <= dis[S]) S = j;
61                 }
62             }
63             vis[S] = 1;
64             //松弛操作
65             for (int j = 0; j < N; j++) {
66                 if (!vis[j]&&road[S][j]!=-1) { //没被访问过并且与当前节点相同的更新值
67                     //dis[j] = min(dis[j], road[S][j] + dis[S]);
68                     int disSum = road[S][j] + dis[S];
69                     if (dis[j] > disSum) {
70                         dis[j] = disSum;
71                         record[j].clear();
72                         record[j].insert(S);
73                     }
74                     else if (dis[j] == disSum) record[j].insert(S);
75                 }
76             }
77         }
78         num = 0; tempRescue = rescue[C2];
79         dfs(record, C2);
80         cout << num << " " << maxRescue << endl;
81     }
82     return 0;
83 }

猜你喜欢

转载自www.cnblogs.com/NiBosS/p/12098527.html