记录一个菜逼的成长。。
题目链接
最快路径其实就是最短路径。
以下数组都在满足最短路条件下
num[i] := 表示到达i点的最短路径数
len[i] := 表示到达i点所经过的点数,不包括起点
tot[i] := 表示到达i点所救的人数
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
using namespace std;
#define cl(a,b) memset(a,b,sizeof(a))
#define ALL(v) (v).begin(),(v).end()
#define MIN(a,b) a < b ? a : b
#define MAX(a,b) a < b ? b : a
#define pb push_back
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = 200 + 10;
int g[maxn][maxn],dis[maxn],vis[maxn],a[maxn];
int num[maxn],len[maxn],tot[maxn],path[maxn];
map<string,int>ma;
map<int,string>mb;
void init(int n)
{
cl(path,-1);
for( int i = 1; i <= n; i++ ){
for( int j = 1; j <= n; j++ )
g[i][j] = INF;
num[i] = 1;
}
}
void dijkstra(int s,int n)
{
cl(vis,0);
fill(dis+1,dis+1+n,INF);
dis[s] = 0;
for( int i = 1; i < n; i++ ){
int mn = INF,x;
for( int j = 1; j <= n; j++ )
if(!vis[j] && dis[j] < mn)mn = dis[x = j];
vis[x] = 1;
for( int j = 1; j <= n; j++ ){
if(dis[j] > dis[x] + g[x][j]){
dis[j] = dis[x] + g[x][j];
path[j] = x;
num[j] = num[x];
len[j] = len[x] + 1;
tot[j] = tot[x] + a[j];
}
else if(dis[j] == dis[x] + g[x][j]){
if(len[j] < len[x] + 1){
len[j] = len[x] + 1;
path[j] = x;
tot[j] = tot[x] + a[j];
}
else if(len[j] == len[x] + 1){
if(tot[j] < tot[x] + a[j]){
tot[j] = tot[x] + a[j];
path[j] = x;
}
}
num[j] += num[x];
}
}
}
}
void print_path(int path[],int e)
{
stack<int>st;
while(e != -1){
st.push(e);
e = path[e];
}
int flag = 1;
while(!st.empty()){
if(flag)cout<<mb[st.top()],flag = 0;
else cout<<"->"<<mb[st.top()];
st.pop();
}
puts("");
}
int main()
{
int n,k;
string s,e,str,str1;
while(cin>>n>>k>>s>>e){
ma[s] = 1;
mb[1] = s;
for( int x,i = 2; i <= n; i++ ){
cin>>str>>x;
ma[str] = i;
mb[i] = str;
a[i] = x;
}
init(n);
for( int i = 1,x; i <= k; i++ ){
cin>>str>>str1>>x;
g[ma[str]][ma[str1]] = MIN(g[ma[str]][ma[str1]],x);
g[ma[str1]][ma[str]] = g[ma[str]][ma[str1]];
}
dijkstra(ma[s],n);
print_path(path,ma[e]);
printf("%d %d %d\n",num[ma[e]],dis[ma[e]],tot[ma[e]]);
}
return 0;
}