天梯赛 直捣黄龙 (多条件Dij)

题目链接:直捣黄龙

 

题目大意:

404

 

解题思路:

给的字符串可以用map来映射到整数序号,多条件就用dijkstra加上一些判断就好。

 

参考代码:

 

 1 #include <bits/stdc++.h>
 2 #define N 410
 3 #define p pair<int,int>
 4 using namespace std;
 5 bool vis[N];
 6 int ed2,ed,n,k,peo[N],pre[N],sum[N],city[N],d[N],num[N]; // city城市和,num路径条数,sum击败人数
 7 struct edge
 8 {
 9     int v,w;
10 };
11 unordered_map<string,int> f; // 字符串到序号
12 unordered_map<int,string> _f; // 序号到字符串映射
13 vector<edge> g[N];
14 inline int read()
15 {
16     int x = 0, y = 1; char c = getchar(); while(c < '0' || c > '9') {if(c == '-') y = -1; c = getchar();} while(c >= '0' && c <= '9') x = x*10+c-'0', c = getchar(); return x*y;
17 }
18 void dijkstra(int s)
19 {
20     memset(vis,false,sizeof(vis)); // 初始化
21     memset(d,0x3f,sizeof(d));
22     memset(pre,-1,sizeof(pre));
23     d[s] = 0; num[s] = 1; city[s] = 0; sum[s] = 0;
24     priority_queue<p, vector<p>, greater<p> > q; // pair以第一个值为主关键字排序
25     q.push({0,s});
26     while(!q.empty())
27     {
28         p t = q.top(); q.pop();
29         int u = t.second;
30         if(vis[u]) continue; // dijkstra用vis
31         else vis[u] = true;
32         for(int i = 0; i < g[u].size(); i++)
33         {
34             int v = g[u][i].v, dis = g[u][i].w;
35             if(d[v] > d[u]+dis) // 先判断距离
36             {
37                 d[v] = d[u]+dis; num[v] = num[u]; sum[v] = sum[u]+peo[v]; city[v] = city[u]+1; pre[v] = u;
38                 q.push({d[v],v});
39             } else if(d[v] == d[u]+dis) {
40                 if(city[v] < city[u]+1) // 根据题目再判断城市
41                 {
42                     city[v] = city[u]+1; pre[v] = u; sum[v] = sum[u]+peo[v];
43                 } else if(city[v] == city[u]+1 && sum[v] < sum[u]+peo[v]) { // 最后判断杀敌数
44                     pre[v] = u; sum[v] = sum[u]+peo[v];
45                 }
46                 num[v] += num[u];
47             }
48             
49         }
50     }
51 }
52 int main()
53 {
54     string s,e;
55     n = read(); k = read(); cin >> s >> e;
56     for(int i = 1; i <= n-1; i++)
57     {
58         string t;
59         cin >> t >> peo[i]; f[t] = i; _f[i] = t;
60     }
61     for(int i = 0,x; i < k; i++)
62     {
63         string t1,t2;
64         cin >> t1 >> t2 >> x;
65         g[f[t1]].push_back({f[t2],x});
66         g[f[t2]].push_back({f[t1],x});
67     }
68     ed2 = f[e]; ed = f[e];
69     dijkstra(f[s]);
70     vector<int> v; // 输出路径
71     while(ed != -1) v.push_back(ed), ed = pre[ed];
72     cout << s;
73     for(int i = v.size()-1; i >= 0; i--) // 倒序输出
74     {
75         cout << _f[v[i]];
76         if(i != 0) printf("->");
77     }
78     printf("\n%d %d %d",num[ed2],d[ed2],sum[ed2]);
79     return 0;
80 }

 

posted @ 2020-11-23 20:12  不敢说的梦  阅读(258)  评论(0)    收藏  举报