n个点m条边,从1号点开始到第i个点的最短距离为
d
i
d_i
di,求
d
2
+
d
3
+
.
.
.
+
d
n
d_2+d_3+...+d_n
d2+d3+...+dn最小值,最短路生成树。首先题目保证图是联通的,从1好点开始跑一个dijksra求出从1号点到每个点的最短距离,然后将连接这些点的边输出。
代码
constint N =2e5+100;int h[N], id[N *2], e[N *2], ne[N *2], w[N *2];
ll dist[N], idx;voidadd(int a,int b,int c,int d){
e[idx]= b, id[idx]= d, w[idx]= c, ne[idx]= h[a], h[a]= idx ++;}bool vis[N];voidsolve(){memset(h,-1,sizeof h);int n, m; cin >> n >> m;for(int i =1; i <= m; i++){int a, b, c; cin >> a >> b >> c;add(a, b, c, i);add(b, a, c, i);}
function<void()> dijkstra =[&](){memset(dist,0x3f,sizeof dist);
dist[1]=0;
priority_queue<pair<ll,int>> pq;
pq.push({0,1});while(pq.size()){auto t = pq.top().second; pq.pop();if(vis[t])continue;
vis[t]=1;for(int i = h[t];~i; i = ne[i]){int j = e[i];if(dist[j]> dist[t]+ w[i]){
dist[j]= dist[t]+ w[i];
pq.push({-dist[j], j});}}}};dijkstra();for(int u =2; u <= n; u++){for(int i = h[u];~i; i = ne[i]){int j = e[i];if(dist[u]== dist[j]+ w[i]){
cout << id[i]<<' ';break;}}}}
voidsolve(){
ll n, l; cin >> n >> l;
priority_queue<ll, vector<ll>, greater<ll>> pq;for(int i =0; i < n; i++){int u; cin >> u;
pq.push(u);
l -= u;}if(l) pq.push(l);
ll ans =0;while(pq.size()>1){auto l = pq.top(); pq.pop();auto r = pq.top(); pq.pop();
ans += l + r;
pq.push(l + r);}
cout << ans <<'\n';}