USACO Dec. 09 过路费
2017年7月14日
简单的图算法
#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;
/*
第1行: 三个空格隔开的整数: N, M和K
第2到第N+1行: 第i+1行包含一个单独的整数: C_i
第N+2到第N+M+1行: 第j+N+1行包含3个由空格隔开的整数: A_j, B_j和L_j
第N+M+2倒第N+M+K+1行: 第i+N+M+1行表示第i个问题,包含两个由空格隔开的整数s_i和t_i
*/
const int V = 260;
int N, M, K;
struct Edges{
int id;
int v;
}E[V];
int Edge[V][V];
int dis[V][V];
int eachV[V];
bool cmp(Edges a, Edges b){
return a.v < b.v;
}
void Putin()
{
memset(Edge, 10, sizeof(Edge));
memset(dis, 10, sizeof(dis));
cin >> N >> M >> K;
for(int i = 1; i <= N; i++){
cin >> E[i].v;
eachV[i] = E[i].v;
E[i].id = i;
//
Edge[i][i] = 0;
dis[i][i] = E[i].v;
}
int ai, bi, li;
for(int i = 1; i <= M; i++){
cin >> ai >> bi >> li;
Edge[ai][bi] = Edge[bi][ai] = min(Edge[ai][bi], li);
}
sort(E + 1, E + N + 1, cmp);
}
void Floyd()
{
for(int j = 1; j <= N; j++){//E[j]
for(int i = 1; i <= N; i++)
for(int k = 1; k <= N; k++){
Edge[i][k] =
min(Edge[i][k], Edge[i][E[j].id] + Edge[E[j].id][k]);
dis[i][k] = min(
dis[i][k], (Edge[i][k] + max(eachV[i], max(eachV[k], E[j].v)))
);
}
}
}
int main()
{
Putin();
Floyd();
for(int i = 1; i <= K; i++){
int si, ti;
cin >> si >> ti;
cout << dis[si][ti] << endl;
}
cout << endl;
return 0;
}