P2966 [USACO09DEC]牛收费路径Cow Toll Paths

之前在最短路模型总结中提到了

Q:除起点与终点外,必须在规定的点上走:
A:将floyd的最外层设为规定的点而不是所有点。

所以这道题直接按照点权从小到大排序然后放在最外层循环, 那么显然当前最外层的点即为路径上点的最大值.
注意因为起点和终点没有按照顺序枚举, 所以整条路上的最大值还有可能是起点或者终点.

#include <vector>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 250 + 5;
inline int read(){
    char ch = getchar(); int x = 0;
    while(!isdigit(ch)) ch = getchar();
    while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
    return x;
}

int N, M, K;
int g[MAXN][MAXN], C[MAXN];
int f[MAXN][MAXN], dis[MAXN][MAXN];

vector<int> nodes;
bool cmp(int &lhs, int &rhs) {
    return C[lhs] < C[rhs];
}

int main(){
    cin>>N>>M>>K;
    memset(g, 0x3f, sizeof(g));
    for(int i = 1; i <= N; i++) C[i] = read();
    for(int i = 1; i <= M; i++) {
        int u = read(), v = read(), c = read();
        if(c < g[u][v]) g[u][v] = g[v][u] = c;
    }
    for(int i = 1; i <= N; i++) nodes.push_back(i);
    sort(nodes.begin(), nodes.end(), cmp);
    
    memset(f, 0x3f, sizeof(f));
    for(int i = 1; i <= N; i++) f[i][i] = 0;
    for(int i = 1; i <= N; i++) g[i][i] = 0;

    for(int k = 0; k < N; k++)
        for(int i = 0; i < N; i++)
            for(int j = 0; j < N; j++) if(i != j) {
                int u = nodes[i], v = nodes[j], p = nodes[k];
                g[u][v] = min(g[u][v], g[u][p] + g[p][v]);
                f[u][v] = min(f[u][v], (g[u][p] + g[p][v]) + max(C[p], max(C[u], C[v])));
            }
    while(K--) {
        int u = read(), v = read();
        printf("%d\n", f[u][v]);
    }
    return 0;
}
posted @ 2018-11-05 16:13  俺是小程  阅读(171)  评论(0编辑  收藏  举报