Topic Link: Click to open the link
Test instructions
The first line input n points m bar can be built without the side K person
Here is the cost of building the side and building the side.
At the beginning of the K-person at each point of the 1-k (one point each)
Objective: To construct a partial edge from a given edge of M bar to make the cost and the minimum
Let the K-man move to the K-point behind [N-k+1, N] (one per point).
Ideas:
First, a Steiner tree, or a DP array (solution: Click to open the link)
DP[I][J] represents the minimum cost for the I root, J for 8 points in the Shari of I.
The question now is how to ask for answers.
Because a man to his target point this path may be disconnected from others, i.e. multiple minimum spanning trees,
We enumerate 2*k points which are in a connected component,
For state x, the binary representation of the person is a low k-bit, indicating that the target point is a high K-bit, and X 1 indicates that the points are in a connected component,
The minimum cost for this x is min (dp[anypoint regard root][x])
x must ensure that the number of 1 in the low K-bit is the same as the number of 1 in the high K-bit (i.e. the number of people and target points)
Then the memory search can be.
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <map> #include <queue> #include <set> #include <algorithm>template <class t>inline BOOL Rd (T &ret) {char c; int sgn; if (c = GetChar (), c = = EOF) return 0; while (c! = '-'-' && (c< ' 0 ' | | c> ' 9 ')) C = GetChar (); SGN = (c = = '-')? -1:1; ret = (c = = '-')? 0: (C-' 0 '); while (c = GetChar (), C >= ' 0 ' &&c <= ' 9 ') ret = ret * + (C-' 0 '); RET *= SGN; return 1;} Template <class t>inline void pt (T x) {if (x <0) {Putchar ('-'); x =-X; } if (X>9) pt (X/10); Putchar (x 10 + ' 0 ');} int Pow (int x, int y) {int ans = 1; while (Y > 0) {if ((Y & 1) > 0) ans *= x; Y >>= 1; x = x * x; } return ans; using namespace Std;const int inf = 1e8;const int n = 55;const int M = 500010;int N, M, K, Ans;int Dis[n][n], dp[n][1 << 10];int e[10];int vis[n];int mem[1 << 10];int Check (int x) {int a = 0, b = 0; for (int i = 0; i < K; i++) if ((x& (1 << i) >0) a++; for (int i = 0; i < K; i++) if ((x& (1 << (i + k)) >0) b++; if (A! = b) return-1; int ans = inf; for (int i = 0; i < n; i++) ans = min (ans, dp[i][x]); return ans;} int dfs (int x) {if (mem[x]! =-1) return mem[x]; int tmp = check (x); if (tmp = =-1) return mem[x] = inf; int ans = tmp; for (int i = (x-1) &x; i > 0; i = (i-1) &x) {ans = min (ans, DFS (i) + DFS (x-i)); } return mem[x] = ans;} void Floyd () {for (int z = 0, z < n; z++) for (int j = 0; J < N; j + +) for (int i = 0; i < n; i++) Dis[i][j] = min (Dis[i][j], dis[j][z] + dis[z][i]);} void input () {rd (n); Rd (M); Rd (k); for (int i = 0, i < n; i++) for (int j = 0; J < N; j + +) Dis[i][j] = (i==j)? 0:inf; int U, V, D; while (m-->0) {rd (U); Rd (v); Rd (D); u--; v--; DIS[U][V] = dis[v][u] = min (dis[u][v], D); } for (int z = 0, z < n; z++) for (int j = 0; J < N; j + +) for (int i = 0; i < n; i++) Dis[i][j] = Min (Dis[i][j], dis[j][z] + dis[z][i]);} int main () {int T; rd (T); while (t-->0) {input (); Floyd (); for (int i = 0; i < K; i++) e[i] = i; for (int i = 0; i < K; i++) E[i + K] = n-k + i; for (int i = 0, i < n; i++) for (int j = 0; J < (1 << (2 * k)); J + +) dp[i][j] = inf; for (int i = 0; i < n; i++.) {for (int j = 0; J < 2 * k, j + +) dp[i][1 << j] = dis[i][ E[J]]; } for (int i = 1; i < (1 << (2 * k)); i++) {if (0 = = (i& (i-1))) continue; for (int j = 0; J < N; j + +) {for (int sub = i; sub > 0; sub = (sub-1) &i) dp[ J][i] = min (Dp[j][i], dp[j][sub] + dp[j][i-sub]); } for (int j = 0; j < N;J + +) Vis[j] = 0; for (int j = 0; J < N; j + +) {int a = INF, pos = 0; for (int z = 0; z < n; z++) if (vis[z] = = 0 && dp[z][i] <= a) a = Dp[pos = Z][i]; Vis[pos] = 1; for (int z = 0; z < n; z++) Dp[pos][i] = min (Dp[pos][i], dp[z][i] + dis[z][pos]); }} for (int j = k; J < 2 * k; j + +) vis[j] = 1; memset (Mem,-1, sizeof mem); Mem[0] = 0; Ans = DFS ((1<< (2*k))-1); if (ans = = inf) printf ("No solution\n"); else printf ("%d\n", ans); } return 0;}
Import Java.io.bufferedreader;import Java.io.inputstreamreader;import Java.io.printwriter;import Java.math.biginteger;import Java.text.decimalformat;import Java.util.arraydeque;import Java.util.ArrayList;import Java.util.arrays;import Java.util.collections;import Java.util.comparator;import Java.util.Deque;import Java.util.hashmap;import Java.util.iterator;import Java.util.linkedlist;import Java.util.Map;import Java.util.priorityqueue;import Java.util.scanner;import Java.util.stack;import Java.util.StringTokenizer;import Java.util.treemap;import Java.util.treeset;import Java.util.queue;import Java.io.file;import Java.io.fileinputstream;import Java.io.filenotfoundexception;import Java.io.fileoutputstream;public class Main {int N, M, K, ans;int[][] dis = new Int[n][n], DP = new int[n][1<<10];int[] e = new int[10];int[] Vis = new Int[n], mem = New Int[1<<10];int Check (int x) {int a = 0, B = 0;for (int i = 0; i < K; i++) if ((x& (1 << i) >0) a++; for (int i = 0; I &lT K i++) if ((x& (1 << (i + k)) >0) b++;if (A! = b) return-1;int ans = inf;for (int i = 0; i < n; i++) ans = min (a NS, dp[i][x]); return ans;} int dfs (int x) {if (mem[x]! =-1) return mem[x];int TMP = check (x), if (tmp = =-1) return mem[x] = inf;int ans = tmp;for (int i = (x-1) &x; i > 0; i = (i-1) &x) {ans = min (ans, DFS (i) + DFS (x-i));} return mem[x] = ans;} void Floyd () {for (int z = 0, z < n; z++) for (int j = 0; J < N; j + +) for (int i = 0; i < n; i++) dis[i][j] = min (dis[i) [j], Dis[j][z] + dis[z][i]);} void input () throws exception{for (int i = 0; i < n; i++) for (int j = 0; J < N; j + +) Dis[i][j] = (i==j)? 0:inf;while (m-- >0) {int u = Int ()-1, v = int ()-1, d = Int ();d is[u][v] = dis[v][u] = min (dis[u][v], d);}} void work () throws Exception{int T = Int (), while (t-->0) {n = int (), m = Int (); k = int (); input (); Floyd (); for (int i = 0 ; I < K; i++) E[i] = i; for (int i = 0, i < K; i++) E[i + K] = n-k + i;for (int i = 0; i < n; i++) for (int j = 0; J <(1 << (2 * k)); J + +) Dp[i][j] = inf;for (int i = 0; i < n; i++) {for (int j = 0; J < 2 * k; + j) dp[i][1 << j] = Dis[i][e[j]];} for (int i = 1; i < (1 << (2 * k)), i++) {if (0 = = (i& (i-1))) continue;for (int j = 0; J < N; j + +) {for t sub = i; Sub > 0; Sub = (sub-1) &i) dp[j][i] = min (Dp[j][i], dp[j][sub] + dp[j][i-sub]);} for (int j = 0; J < N; j + +) Vis[j] = 0;for (int j = 0; J < N; j + +) {int a = INF, pos = 0;for (int z = 0; z < n; z++ if (vis[z] = = 0 && dp[z][i] <= a) a = Dp[pos = Z][i];vis[pos] = 1;for (int z = 0; z < n; z++) dp[pos][i] = mi N (dp[pos][i], dp[z][i] + dis[z][pos]);}} for (int i = 1; i < (1<< (2*k)); i++) mem[i] = -1;mem[0] = 0;ans = DFS ((1<< (2*k))-1); if (ans = = inf) out.println ("No solution"); else out.println (ans);}} public static void Main (string[] args) throws exception{main wo = new main (); in = new BufferedReader (new InputStreamReader (system.in)); out = new PrintWriter (System.out); //in = new BufferedReader (new InputStreamReader (New FileInputStream (New File ("Input.txt"))); out = new PrintWriter (New File ("output.txt")); Wo.work (); Out.close (); }static int N = 55;static int M = 2005;decimalformat df=new decimalformat ("0.0000"); static int inf = (int) 1e8;static long INF64 = (long) 1e18*2;static double EPS = 1e-8;static double Pi = math.pi;static int mod = 1000000009;p rivate String Next () throws exception{while (str = = NULL | |!str.hasmoreelements ()) str = new StringTokenizer (In.readline ()); return Str.nexttoken (); } private int int () throws exception{return Integer.parseint (Next ()); } Private Long Long () throws exception{return Long.parselong (Next ()); } private double double () throws exception{return Double.parsedouble (Next ()); } StringTokenizer str; static Scanner cin = new Scanner (system.in); Static BufferedReader in; static PrintWriter out; /* Class Edge{int from, to, DIS, NEX; EdGE () {}edge (int from, int. to, int dis, int nex) {This.from = From;this.to = To;this.dis = Dis;this.nex = NEX;}} Edge[] Edge = new edge[m<<1];int[] head = new Int[n];int edgenum;void Init_edge () {for (int i = 0; i < N; i++) head[ I] =-1; Edgenum = 0;} void Add (int u, int v, int dis) {Edge[edgenum] = new Edge (u, V, dis, head[u]); Head[u] = edgenum++;} /**/int Upper_bound (int[] A, int l, int r, int val) {//Upper_bound (a+l,a+r,val)-a;int pos = R;r--;while (l <= r) {int Mid = (L + R) >> 1;if (A[mid] <= val) {L = mid + 1;} else {pos = Mid;r = Mid-1;}} return POS;} int Pow (int x, int y) {int ans = 1;while (Y > 0) {if ((Y & 1) > 0) ans *= x;y >>= 1;x = x * x;} return ans;} Double Pow (double x, int y) {double ans = 1;while (Y > 0) {if ((Y & 1) > 0) ans *= x;y >>= 1;x = x * x;} return ans;} int pow_mod (int x, int y, int Mod) {int ans = 1;while (Y > 0) {if ((Y & 1) > 0) ans *= x;ans%= mod;y >>= 1 ; x = x * x;x%= mod;} return ans;} Long Pow (long x, long y) {long ans = 1;while (Y > 0) {if ((Y & 1) > 0) ans *= x;y >>= 1;x = x * x;} return ans;} Long Pow_mod (long x, long y, long Mod) {Long ans = 1;while (Y > 0) {if ((Y & 1) > 0) ans *= x;ans%= mod;y >&G t;= 1;x = x * x;x%= mod;} return ans;} int gcd (int x, int y) {if (x>y) {int tmp = x; x = y; y = tmp;} while (x>0) {y%= x;int tmp = x; x = y; y = tmp;} return y;} int max (int x, int y) {return x > y x:y;} int min (int x, int y) {return x < y x:y;} Double Max (double x, double y) {return x > y x:y;} Double min (double x, double y) {return x < y x:y;} Long Max (long x, long y) {return x > y x:y;} Long min (long x, long y) {return x < y x:y;} int abs (int x) {return x > 0 ×:-X;} Double abs (double x) {return x > 0 ×:-X;} Long ABS (long x) {return x > 0 ×:-X;} Boolean zero (double x) {return abs (x) < EPS;} Double sin (double x) {return Math.sin (x);} Double cos (double x) {return math.cos (x);} Double tan (double x) {return MatH.tan (x);} Double sqrt (double x) {return math.sqrt (x);}}
HDU 4085 Peach Blossom Spring Memory Search Enumeration subset Eectilinear