题目链接:http://csustacm.com:4803/problem/1016
题目:
思路:状压dp+最短路,比赛的时候有想到状压dp,但是最短路部分写挫了,然后就卡死了,对不起出题人~dis[i][j]表示状态i下目的地为j时的最短路。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <queue> 4 #include <stack> 5 #include <cmath> 6 #include <bitset> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstdlib> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 16 typedef long long ll; 17 typedef pair<ll, ll> pll; 18 typedef pair<ll, int> pli; 19 typedef pair<int, ll> pil;; 20 typedef pair<int, int> pii; 21 typedef unsigned long long ull; 22 23 #define lson i<<1 24 #define rson i<<1|1 25 #define bug printf("********* "); 26 #define FIN freopen("D://code//in.txt", "r", stdin); 27 #define debug(x) cout<<"["<<x<<"]" <<endl; 28 #define IO ios::sync_with_stdio(false),cin.tie(0); 29 30 const double eps = 1e-8; 31 const int mod = 10007; 32 const int maxn = 2e5 + 7; 33 const double pi = acos(-1); 34 const int inf = 0x3f3f3f3f; 35 const ll INF = 0x3f3f3f3f3f3f3f; 36 37 int n, m, u, v, w; 38 ll ans; 39 int val[maxn], vis[10][maxn]; 40 ll dis[10][maxn]; 41 42 struct edge { 43 int v, w; 44 edge(int v, int w) : v(v), w(w) {} 45 }; 46 47 struct node { 48 int v, sta; 49 ll w; 50 node(int v, int sta, ll w) : v(v), sta(sta), w(w) {} 51 bool operator < (const node& x) const { 52 return w > x.w; 53 } 54 }; 55 56 vector<edge> G[maxn]; 57 58 void dij() { 59 memset(vis ,0, sizeof(vis)); 60 memset(dis, inf, sizeof(dis)); 61 priority_queue<node> q; 62 q.push(node(1, (1<<val[1]), 0)); 63 dis[1<<val[1]][1] = 0; 64 while(!q.empty()) { 65 node e = q.top(); q.pop(); 66 int u = e.v, sta = e.sta; 67 if(vis[sta][u]) continue; 68 vis[sta][u] = 1; 69 for(int i = 0; i < G[u].size(); i++) { 70 int v = G[u][i].v, nw = sta | (1<<val[v]); 71 ll w = G[u][i].w; 72 if(dis[nw][v] > dis[sta][u] + w) { 73 dis[nw][v] = dis[sta][u] + w; 74 q.push(node(v, nw, dis[nw][v])); 75 } 76 } 77 } 78 } 79 80 int main() { 81 //FIN; 82 scanf("%d%d", &n, &m); 83 for(int i = 1; i <= n; i++) { 84 scanf("%d", &val[i]); 85 } 86 for(int i = 1; i <= m; i++) { 87 scanf("%d%d%d", &u, &v, &w); 88 G[u].push_back(edge(v, w)); 89 G[v].push_back(edge(u, w)); 90 } 91 dij(); 92 ans = min(dis[6][1], dis[7][1]); 93 printf("%lld ", ans); 94 return 0; 95 }