zoukankan      html  css  js  c++  java
  • 1003_Emergency (25分)[最短路Dijkstra]

    题意:计算从城市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 }
  • 相关阅读:
    workflow里xaml格式(备忘)
    Excel 读取
    自定义工作流活动的外观的两种方式(补充)
    用SQLite,Enterprise的报错
    WF 4.0
    升级 90天 vs2008 在win2008下。
    NUnitLite web下的用法
    screen常用方法 Lei
    中文摘要的写法 Lei
    bootstrap, boosting, bagging 几种方法的联系 Lei
  • 原文地址:https://www.cnblogs.com/NiBosS/p/12098527.html
Copyright © 2011-2022 走看看