【CCCC】L3-011 直捣黄龙 (30分)，Dijkstra维护点权，节点数，路径条数等+路径打印

problem

L3-011 直捣黄龙 (30分)

10 12 PAT DBY
DBY 100
PTA 20
PDS 90
PMS 40
TAP 50
ATP 200
LNN 80
LAO 30
LON 70
PAT PTA 10
PAT PMS 10
PAT ATP 20
PAT LNN 10
LNN LAO 10
LAO LON 10
LON DBY 10
PMS TAP 10
TAP DBY 10
DBY PDS 10
PDS PTA 10
DBY ATP 10

PAT->PTA->PDS->DBY
3 30 210

• 给出n个点，k条边的图，求最短路
• 满足经过节点最多，其次点权和最大
• 输出唯一路径，最短路条数，长度，以及点权和

solution

• 吐槽一下：又是最短路，又是Dijkstra，这是我在PTA打过的唯一一个算法了，好没劲啊。
Bellman-Ford不香么，队列优化的SPFA不香么，Dij连heap优化都没写过
搞得再这样我就只会dij了，，连个MST都没考过，Kruskal,Prim都是模板啊，什么鬼嘛

• 城镇代号，hash成数字把。

• 第一次WA1,2,4发现输出看错了，是最短路条数，不是经过的点数，这样例也太水了

#include<bits/stdc++.h>
using namespace std;
const int maxn = 250;

map<string,int>ma;
map<int,string>mb;
int tot = 1;
int getid(string s){
if(ma.count(s))return ma[s];
else{
mb[tot] = s;
ma[s] = tot;
tot++;
return ma[s];
}
}

int n, k, s, t;
int e[maxn][maxn], w[maxn];
int dist[maxn], vis[maxn], pre[maxn], cnt[maxn], weight[maxn], cc[maxn];
void Dijkstra(int u){
memset(dist, 0x3f,sizeof(dist));
memset(pre,-1,sizeof(pre));
dist[u] = 0; cnt[u] = 0; weight[u]=w[u];  cc[u] = 1;
for(int i = 1; i <= n; i++){
int v = -1, minn = 1e9;
for(int j = 1; j <= n; j++){
if(!vis[j] && dist[j]<minn){
minn = dist[j];
v = j;
}
}
vis[v] = 1;
for(int j = 1; j <= n; j++){
if(!vis[j] && dist[j]>dist[v]+e[v][j]){
dist[j] = dist[v]+e[v][j];
cc[j] = cc[v];
cnt[j] = cnt[v]+1;
weight[j] = weight[v]+w[j];
pre[j] = v;
}else if(!vis[j] && dist[j]==dist[v]+e[v][j]){
cc[j] += cc[v];//+=
if(cnt[j]<cnt[v]+1){
cnt[j] = cnt[v]+1;
weight[j] = weight[v]+w[j];
pre[j] = v;
}else if(cnt[j]==cnt[v]+1){
if(weight[j]<weight[v]+w[j]){
weight[j] = weight[v]+w[j];
pre[j] = v;
}
}
}
}
}
}

int main(){
cin>>n>>k;
string a,b;  cin>>a>>b;
s = getid(a);  t = getid(b);
memset(e,0x3f,sizeof(e));
for(int i = 1; i < n; i++){
string a; int b;  cin>>a>>b;
w[getid(a)] = b;
}
for(int i = 1; i <= k; i++){
string a, b;  cin>>a>>b;
int aa = getid(a), bb = getid(b);
int cc;  cin>>cc;
e[aa][bb] = e[bb][aa] = cc;
}
Dijkstra(s);
vector<string>vec;
int x = t;
while(x!=-1){
vec.push_back(mb[x]);
x = pre[x];
}
reverse(vec.begin(),vec.end());
for(int i = 0; i < vec.size(); i++){
if(i==vec.size()-1)cout<<vec[i]<<endl;
else cout<<vec[i]<<"->";
}
cout<<cc[t]<<" "<<dist[t]<<" "<<weight[t]<<"\n";
return 0;
}



08-18 128
09-09 1633
07-18 6921
06-06 2881
04-09 555
03-28 815
03-27 1204
07-19 2392
03-26 2725
07-12 764