题意:计算从城市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 }
1003_Emergency (25分)[最短路Dijkstra]
原文:https://www.cnblogs.com/NiBosS/p/12098527.html