天梯赛 直捣黄龙 (多条件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 }

浙公网安备 33010602011771号