#include #include #include #include #include #include #include #include #include #include using namespace std; const int MAXN = 5005; const int64_t inf = 1e18; mt19937 rnd(22); struct Graph { int n; vector > adj[MAXN]; Graph() { memset(dist, -1, sizeof(dist)); memset(distCalculated, false, sizeof(distCalculated)); } int64_t dist[MAXN][MAXN]; void addEdge(int u, int v, int val) { adj[u].emplace_back(v, val); adj[v].emplace_back(u, val); } using DijkstraPQ = priority_queue , vector >, greater >>; void useVertex(int start, int x, DijkstraPQ &pq) { for(auto e: adj[x]) { if(dist[start][e.first] > dist[start][x] + e.second) { dist[start][e.first] = dist[start][x] + e.second; pq.emplace(dist[start][e.first], e.first); } } } bool distCalculated[MAXN]; vector allDistCalculated; void initDistSingle(int start) { distCalculated[start] = true; allDistCalculated.push_back(start); DijkstraPQ pq; for(int x = 1;x<=n;x++) dist[start][x] = inf; pq.emplace(0, start); dist[start][start] = 0; while(pq.empty()==false) { int x = pq.top().second; int64_t d = pq.top().first; pq.pop(); if(dist[start][x]!=d) continue; useVertex(start, x, pq); } } void initDistAll() { for(int start = 1;start<=n;start++) { initDistSingle(start); } } int64_t getDistAprox(int u, int v) { if(dist[u][v]!=-1) return dist[u][v]; if(dist[v][u]!=-1) return dist[u][v]; int64_t ans = inf; for(int mid: allDistCalculated) ans = min(ans, dist[mid][u] + dist[mid][v]); dist[u][v] = dist[v][u] = ans; return ans; } }; struct ProbabilityGraph { int n; vector > adj[MAXN]; void addEdge(int u, int v, double val) { adj[u].emplace_back(v, val); } }; int n, k; int subtask; void input(Graph &G, ProbabilityGraph &PG) { #ifndef _LOCAL_ ifstream cin("newyear.in"); #endif // _LOCAL_ int m, l; cin >> n >> m >> l >> k; G.n = n; PG.n = n; for(int i = 0;i> a >> b >> val; G.addEdge(a, b, val); } for(int i = 0;i> a >> b >> val; PG.addEdge(a, b, val); } } struct Configuration { vector houses; vector home; double value = inf; void reset() { houses.clear(); if(home.size()!=n) home.resize(n+1); } }; Graph G; ProbabilityGraph PG; double evalSlow(Configuration &config) { double value = 0; double ev[2][MAXN], chance[2][MAXN]; for(int x = 1;x<=n;x++) ev[0][x] = chance[0][x] = 0; chance[0][1] = 1.0; ev[0][1] = G.dist[1][config.home[1]]; value += ev[0][1]; for(int iter = 1;iter<200;iter++) { for(int x = 1;x<=n;x++) ev[iter&1][x] = chance[iter&1][x] = 0; for(int x = 1;x<=n;x++) { for(auto e: PG.adj[x]) { chance[iter&1][e.first] += chance[(iter&1)^1][x]*e.second; ev[iter&1][e.first] += e.second*ev[(iter&1)^1][x] + chance[(iter&1)^1][x]*e.second*(G.dist[config.home[x]][e.first] + G.dist[e.first][config.home[e.first]]); } } for(int x = 1;x<=n;x++) value += ev[iter&1][x]; } return value; } double evalFast(Configuration &config) { double value = 0; double ev[2][MAXN], chance[2][MAXN]; for(int x = 1;x<=n;x++) ev[0][x] = chance[0][x] = 0; chance[0][1] = 1.0; ev[0][1] = G.getDistAprox(1, config.home[1]); value += ev[0][1]; for(int iter = 1;iter<25;iter++) { for(int x = 1;x<=n;x++) ev[iter&1][x] = chance[iter&1][x] = 0; for(int x = 1;x<=n;x++) { if(chance[(iter&1)^1][x]<0.00001) continue; for(auto e: PG.adj[x]) { chance[iter&1][e.first] += chance[(iter&1)^1][x]*e.second; ev[iter&1][e.first] += e.second*ev[(iter&1)^1][x] + chance[(iter&1)^1][x]*e.second*(G.getDistAprox(config.home[x], e.first) + G.getDistAprox(e.first, config.home[e.first])); } } for(int x = 1;x<=n;x++) value += ev[iter&1][x]; } return value; } double genConfigurationSlow(vector &nodeShuffle, Configuration &config) { config.reset(); for(int i = 0;i &nodeShuffle, Configuration &config) { config.reset(); for(int i = 0;i nodeShuffle; for(int x = 1;x<=n;x++) nodeShuffle.push_back(x); shuffle(nodeShuffle.begin(), nodeShuffle.end(), rnd); if(n<=1000) G.initDistAll(); else { for(int i = 0;icurrConfig.value) bestConfig = currConfig; } } else { Configuration currConfig; vector > vertexEccentricity; for(int x = 1;x<=n;x++) { int64_t maxDist = -1; for(int y = 1;y<=n;y++) maxDist = max(maxDist, G.getDistAprox(x, y)); vertexEccentricity.emplace_back(maxDist, x); } sort(vertexEccentricity.begin(), vertexEccentricity.end()); nodeShuffle.clear(); for(auto item: vertexEccentricity) nodeShuffle.push_back(item.second); genConfigurationFast(nodeShuffle, currConfig); if(bestConfig.value>currConfig.value) bestConfig = currConfig; while((clock() - startTime)/CLOCKS_PER_SEC < 3.7) { shuffle(nodeShuffle.begin(), nodeShuffle.end(), rnd); genConfigurationFast(nodeShuffle, currConfig); if(bestConfig.value>currConfig.value) bestConfig = currConfig; } } output(bestConfig); }