额。。。斯坦纳树参见:http://endlesscount.blog.163.com/blog/static/821197872012525113427573
#include <iostream> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <cstdlib> #include <cmath> #include <time.h> #define maxn 2005 #define maxm 4005 #define eps 1e-7 #define mod 1000000007 #define INF 0x3f3f3f3f #define PI (acos(-1.0)) #define lowbit(x) (x&(-x)) #define mp make_pair #define ls o<<1 #define rs o<<1 | 1 #define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R #define pii pair<int, int> #pragma comment(linker, "/STACK:16777216") typedef long long LL; typedef unsigned long long ULL; //typedef int LL; using namespace std; LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;} LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;} // head struct Edge { int v, w; Edge *next; }*H[maxn], E[maxm], *edges; queue<pair<int, int> > q; bool in[55][maxn]; int d[55][maxn]; int dp[maxn]; int p[55]; int n, m, k, o; void addedges(int u, int v, int w) { edges->v = v; edges->w = w; edges->next = H[u]; H[u] = edges++; } void init() { edges = E; memset(H, 0, sizeof H); memset(p, 0, sizeof p); memset(in, 0, sizeof in); memset(d, INF, sizeof d); memset(dp, INF, sizeof dp); } void read() { int u, v, w; scanf("%d%d%d", &n, &m, &k); while(m--) { scanf("%d%d%d", &u, &v, &w); addedges(u, v, w); addedges(v, u, w); } for(int i = 1; i <= k; i++) { p[i] = 1 << i - 1; p[n-i+1] = 1 << k + i - 1; d[i][p[i]] = d[n-i+1][p[n-i+1]] = 0; } o = 1 << k * 2; } bool update(int x, int y, int w) { if(d[x][y] > w) { d[x][y] = w; return true; } else return false; } bool check(int x) { int res = 0; for(int i = 0; x; x >>= 1, i++) res += (x & 1) * (i < k ? 1 : -1); return res == 0; } void spfa() { while(!q.empty()) { int x = q.front().first, y = q.front().second; q.pop(), in[x][y] = false; for(Edge *e = H[x]; e; e = e->next) { int v = e->v, w = e->w; if(update(v, y | p[v], w + d[x][y]) && !in[v][y]) { in[v][y] = true; q.push(mp(v, y)); } } } } void work() { for(int y = 0; y < o; y++) { for(int x = 1; x <= n; x++) { for(int i = (y - 1) & y; i; i = (i - 1) & y) d[x][y] = min(d[x][y], d[x][i | p[x]] + d[x][y - i | p[x]]); if(d[x][y] < INF) q.push(mp(x, y)), in[x][y] = true; } spfa(); } for(int i = 0; i < o; i++) { for(int j = 1; j <= n; j++) dp[i] = min(dp[i], d[j][i]); } for(int i = 0; i < o; i++) if(check(i)) for(int j = (i - 1) & i; j; j = (j - 1) & i) if(check(j)) dp[i] = min(dp[i], dp[i - j] + dp[j]); if(dp[o-1] == INF) printf("No solution\n"); else printf("%d\n", dp[o-1]); } int main() { int _; while(scanf("%d", &_)!=EOF) { while(_--) { init(); read(); work(); } } return 0; }