Gym - 101020H Weekend floyd+next_permutation

https://vjudge.net/problem/Gym-101020H

题意:正常读取方式给你一个图(双向的),然后给你f个点,让你找一条路从1到n的最短路,要求经过f个点(以任意顺序)。

题解:一开始还想dijkstra+dp,发现根本下不了手。后来看了题解,发现只要floyd+next_permutation .Orz

ac代码:

#include<iostream>
#include<algorithm>
#include<string.h>
#include<cstdio>
using namespace std;
int mp[105][105], d[105][105];
int order[12], pos[12];
int main() {
    int t;
    cin >> t;
    int kase = 1;
    while (t--) {
        int n, m, f;
        cin >> n >> m >> f;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                if (i == j)d[i][j] = 0;
                else d[i][j] = 1e9;
                for (int i = 1; i <= m; i++) {
                    int u, v, z;
                    cin >> u >> v >> z;
                    d[u][v] = d[v][u] = z;
                }
                for (int i = 1; i <= f; i++) {
                    cin >> pos[i];
                }

                for (int k = 1; k <= n; k++)
                    for (int i = 1; i <= n; i++)
                        for (int j = 1; j <= n; j++)
                            d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
                for (int i = 1; i <= f; i++)order[i] = i;
                int ans = 1e9, temp = 0;
                do {
                    temp = d[1][pos[order[1]]] + d[n][pos[order[f]]];
                    for (int i = 1; i < f; i++)temp += d[pos[order[i]]][pos[order[i + 1]]];
                    ans = min(ans, temp);
                } while (next_permutation(order + 1, order + 1 + f));
                printf("Case %d: %d\n", kase++, ans);//cout << ans << endl;
    }
}

 

posted @ 2018-03-09 19:12  SuuTTT  阅读(210)  评论(0编辑  收藏  举报