D郊区春游

https://www.nowcoder.com/acm/contest/134/D


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

typedef vector<int> vi;
typedef vector<vi> vii;
typedef vector<ll> vll;

const int MAXN = 1e6 + 10;
const ll INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;
const double eps = 1e-8;

int n, m, k;
vi p;
vii path, dp;

int main(void)
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << setprecision(10) << fixed;
	cin >> n >> m >> k;
	p.resize(k);
	for(int i = 0; i < k; i++){
		cin >> p[i];
		p[i]--;
	}
	path.resize(n, vi(n, INF));
	for(int i = 0; i < m; i++){
		int u, v, c;
		cin >> u >> v >> c;
		u--;
		v--;
		path[u][v] = c;
		path[v][u] = c;
	}
	for(int i = 0; i < n; i++)
		path[i][i] = 0;
	for(int t = 0; t < n; t++)
		for(int i = 0; i < n; i++)
			for(int j = 0; j < n; j++)
				path[i][j] = min(path[i][j], path[i][t] + path[t][j]);
	dp.resize(1 << k, vi(k, INF));
	for(int i = 0; i < k; i++)//状压dp
		dp[1 << i][i] = 0;
	for(int i = 0; i < (1 << k); i++){
		for(int j = 0; j < k; j++){//j代表去过的点
			if(!(i & (1 << j)))
				continue;
			for(int t = 0; t < k; t++){//t代表没去的点
				if((1 << t) & i)
					continue;
				dp[i | (1 << t)][t] = min(dp[i | (1 << t)][t], dp[i][j] + path[p[j]][p[t]]);
			}
		}
	}
	int res = INF;
	for(int i = 0; i < k; i++)
		res = min(res, dp[(1 << k) - 1][i]);
	cout << res << endl;
	cerr << "execute time : " << (double)clock() / CLOCKS_PER_SEC << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43870114/article/details/89789871