Subway upgrade
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 373 Accepted Submission(s): 110
Problem Description
As we all know, one of the most important inventions for modern-day public transportation is the subway, which brings much convenience to our daily-life and saves us from the congested traffic.
However, to hold the next ACM regional contest, you, as the mayor of city X, decided to upgrade the subway system of that city. There are some stations and roads in the city now, any road has a cost. To save money, you decided not to construct every road, but to make sure that there exist a path between every two stations.
Sorry, the mission isn't completed. You know, there are n stations in the city,some contestants visit other stations regularly to admire some so-called big cows. Being naturally averse to spending hours each day on commuting, you should help them to find a place to live for which the total travel time is minimal.
Every road has an ID, from 1 to m. If there are multiple approaches leading to the same minimal cost, the mayor prefers the one of which road IDs selected holds the smallest lexicographic order. For instance, rebuilding ID ( 1 3 5) and ID (2 4 5) will both ensure the minimum cost,the mayor will choose the former one.
However, to hold the next ACM regional contest, you, as the mayor of city X, decided to upgrade the subway system of that city. There are some stations and roads in the city now, any road has a cost. To save money, you decided not to construct every road, but to make sure that there exist a path between every two stations.
Sorry, the mission isn't completed. You know, there are n stations in the city,some contestants visit other stations regularly to admire some so-called big cows. Being naturally averse to spending hours each day on commuting, you should help them to find a place to live for which the total travel time is minimal.
Every road has an ID, from 1 to m. If there are multiple approaches leading to the same minimal cost, the mayor prefers the one of which road IDs selected holds the smallest lexicographic order. For instance, rebuilding ID ( 1 3 5) and ID (2 4 5) will both ensure the minimum cost,the mayor will choose the former one.
Input
First,a number t,indicating the number of the testcases.
For every testcase, there is a number n and m,n(1<=n<=50000) indicating the number of cities,whereas m (0<=m<=500000) indicating the number of roads.
then m lines follow each lines contains three integers a,b,c.(1<=a,b<=n&&a!=b,1<=c<=10000)which means there is a road from a to b whose cost is c.
For every testcase, there is a number n and m,n(1<=n<=50000) indicating the number of cities,whereas m (0<=m<=500000) indicating the number of roads.
then m lines follow each lines contains three integers a,b,c.(1<=a,b<=n&&a!=b,1<=c<=10000)which means there is a road from a to b whose cost is c.
Output
First the minimum cost.If doesn't exist,only output "Poor mayor."(without quotes)
Then output the answer and all the candidate stations.
Then output the answer and all the candidate stations.
Sample Input
3 3 3 1 2 10 2 3 20 3 1 15 3 1 1 2 15 2 1 1 2 15
Sample Output
25 1 50 Poor mayor. 15 1 2 30 Hint: In the first sample we use road 1 and 3 ,the minimus cost is 10+15=25 and we get a new graph 3-1-2,city 1 is the best answer ,2*10+2*15=50 Whereas the third, we can't get city 1,2,3 connected. In the last, we choose the road 1,the minimus cost is 15 and we get a new graph 1-2,both city 1 and city 2 are the best answer ,2*15=30
题意:求最小生成树,并且求哪些点距离其他点距离之和最小。
思路:krasual求最小生成树,然后两次树dp求出每个点到其他点的距离之和。
AC代码:
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <queue>
#include <ctime>
#include <vector>
#include <algorithm>
#define ll long long
#define L(rt) (rt<<1)
#define R(rt) (rt<<1|1)
using namespace std;
const int INF = 1e9;
const int maxn = 50005;
struct Edge{
int v, w, next;
}et[maxn * 4];
struct node{
int u, v, l, id;
}ed[maxn * 10];
int eh[maxn], fa[maxn], son[maxn], ans[maxn];
ll dis1[maxn], dis2[maxn];
int n, m, num;
ll Min;
void init(){
memset(eh, -1, sizeof(eh));
for(int i = 1; i <= n; i++) fa[i] = i;
num = 0;
}
void add(int u, int v, int w){
Edge e = {v, w, eh[u]};
et[num] = e;
eh[u] = num++;
}
int find(int x){
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
bool cmp(node a, node b){
if(a.l != b.l) return a.l < b.l;
return a.id < b.id;
}
void dfs1(int u, int pre){
son[u] = 1;
dis1[u] = 0;
for(int i = eh[u]; i != -1; i = et[i].next)
{
int v = et[i].v, w = et[i].w;
if(v == pre) continue;
dfs1(v, u);
son[u] += son[v];
dis1[u] += son[v] * w + dis1[v];
}
}
void dfs2(int u, int pre, int pedge){
if(pre == -1) dis2[u] = 0;
else dis2[u] = dis2[pre] + dis1[pre] - dis1[u] - son[u] * pedge + ((ll)n - son[u]) * pedge;
for(int i = eh[u]; i != -1; i = et[i].next)
{
int v = et[i].v, w = et[i].w;;
if(v == pre) continue;
dfs2(v, u, w);
}
if(Min > dis1[u] + dis2[u]) Min = dis1[u] + dis2[u];
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &n, &m);
init();
for(int i = 0; i < m; i++)
{
scanf("%d%d%d", &ed[i].u, &ed[i].v, &ed[i].l);
ed[i].id = i;
}
sort(ed, ed + m, cmp);
ll ans1 = 0;
for(int i = 0; i < m; i++)
{
int u = ed[i].u, v = ed[i].v, l = ed[i].l;
int ru = find(u), rv = find(v);
if(ru == rv) continue;
fa[ru] = rv;
add(u, v, l);
add(v, u, l);
ans1 += l;
}
int cnt = 0;
for(int i = 1; i <= n; i++)
if(i == find(i)) cnt++;
if(cnt > 1)
{
printf("Poor mayor.\n");
continue;
}
Min = 0x7fffffffffffffffLL;
dfs1(1, -1);
dfs2(1, -1, 0);
printf("%I64d\n", ans1);
cnt = 0;
for(int i = 1; i <= n; i++)
if(dis1[i] + dis2[i] == Min)
ans[cnt++] = i;
for(int i = 0; i < cnt - 1; i++)
printf("%d ", ans[i]);
printf("%d\n", ans[cnt - 1]);
printf("%I64d\n", 2 * Min);
}
return 0;
}