1. 程式人生 > 其它 >E - Road Reduction

E - Road Reduction

E - Road Reduction (atcoder.jp)

題意:一棵樹n個點,m條路, di表示1-i的距離,問怎麼選擇邊可以使得d2+...dn最短。

題解: 很明顯,就是直接套最短路板子,判斷每一個點的最短路,題目裡沒有負權值,直接dijkstra就可以了。邊如何記錄,與每個點相連的那個最短路的邊,每次更新出來儲存,然後直接輸出即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int N=5e5+5;
ll vis[N],pre[N];
ll dis[N],cnt,head[N];
ll ans[N];
struct ss{ ll next,to,w,id; }e[N]; void add(ll x,ll y,ll w,ll id){ e[++cnt].to=y; e[cnt].w=w; e[cnt].id=id; e[cnt].next=head[x]; head[x]=cnt; } void dij(){ priority_queue<pll,vector<pll>,greater<pll> >q; memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); q.push({
0,1}); dis[1]=0; while(!q.empty()){ ll v=q.top().first; ll u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=1; for(ll i=head[u];i;i=e[i].next){ ll j=e[i].to; if(dis[j]>v+e[i].w){ dis[j]=dis[u]+e[i].w; q.push({dis[j],j}); ans[j]
=e[i].id; } } } } signed main(){ ios::sync_with_stdio(false); cin.tie(0); ll n,m;cin>>n>>m; for(ll i=1;i<=m;i++){ ll x,y,w;cin>>x>>y>>w; add(x,y,w,i); add(y,x,w,i); } dij(); for(int i=2;i<=n;i++){ cout<<ans[i]<<" "; } }