标签:php void class mes color 代码 define .com target
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=1097
[算法]
首先,用Dijkstra算法求出2-k+1到每个点的最短路
然后,我们用f[S][i]表示目前停留城市集合为S,现在在城市i,最短的路径
状压DP即可
[代码]
#include<bits/stdc++.h> using namespace std; #define MAXN 20010 #define MAXM 200010 #define MAXK 25 const int INF = 2e9; const int MAXS = 1 << 20; int i,j,x,n,m,k,u,v,w,tot,g,ts,ans,Mask; int head[MAXN],s[MAXK]; int dist[MAXK][MAXN],f[MAXS][MAXK]; bool visited[MAXN]; struct Edge { int to,w,nxt; } e[MAXM << 1]; inline void addedge(int u,int v,int w) { tot++; e[tot] = (Edge){v,w,head[u]}; head[u] = tot; } inline void dijkstra(int s) { int i,v,w; priority_queue< pair<int,int> > q; pair<int,int> cur; for (i = 1; i <= n; i++) { dist[s][i] = INF; visited[i] = false; } dist[s][s] = 0; q.push(make_pair(0,s)); while (!q.empty()) { cur = q.top(); q.pop(); if (visited[cur.second]) continue; visited[cur.second] = true; for (i = head[cur.second]; i; i = e[i].nxt) { v = e[i].to; w = e[i].w; if (dist[s][cur.second] + w < dist[s][v]) { dist[s][v] = dist[s][cur.second] + w; q.push(make_pair(-dist[s][v],v)); } } } } int main() { scanf("%d%d%d",&n,&m,&k); for (i = 1; i <= m; i++) { scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); addedge(v,u,w); } scanf("%d",&g); for (i = 1; i <= g; i++) { scanf("%d%d",&u,&v); s[v] |= (1 << (u - 2)); } for (i = 1; i <= k + 1; i++) dijkstra(i); Mask = (1 << k) - 1; for (i = 0; i <= Mask; i++) { for (j = 1; j <= k + 1; j++) { f[i][j] = INF; } } for (i = 2; i <= k + 1; i++) { if (!s[i]) f[1 << (i - 2)][i] = dist[i][1]; } f[0][1] = 0; for (i = 0; i <= Mask; i++) { for (j = 1; j <= k + 1; j++) { for (x = 2; x <= k + 1; x++) { ts = i | (1 << (x - 2)); if (((s[x] & i) == s[x]) && f[i][j] + dist[j][x] < f[ts][x]) f[ts][x] = f[i][j] + dist[j][x]; } } } ans = INF; for (i = 1; i <= k + 1; i++) ans = min(ans,f[Mask][i] + dist[i][n]); printf("%d\n",ans); return 0; }
标签:php void class mes color 代码 define .com target
原文地址:https://www.cnblogs.com/evenbao/p/9343444.html