C-点权_牛客练习赛93 (nowcoder.com)
题意:
思路:
重要的是在松弛的时候要满足什么条件才开始松弛
这里是用两个点来松弛一个点
Code:
#include <bits/stdc++.h>//#define int long longusing namespace std;const int mxn=1e5+10;
const int mxv=1e5+10;
const int mxe=1e5+10;
const int mod=1e9+7;
const int Inf=0x3f3f3f3f;struct ty{int to,next,w;
}edge[mxe<<2];struct ty2{int x,dis;bool operator<(const ty2&oth)const{return oth.dis<dis;}
};multiset<int> S[mxn];priority_queue<ty2> Q;int N,u,v,w;
int tot=0;
int head[mxn],in[mxn];
int vis[mxn],dis[mxn];void add(int u,int v,int w){edge[tot].w=w;edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++;
}
void G_init(){tot=0;for(int i=0;i<=N;i++) head[i]=-1;
}
int get(int u){return (*S[u].begin())+(*(++S[u].begin()));
}
void dij(){memset(dis,0x3f,sizeof(dis));memset(vis,0,sizeof(vis));for(int i=1;i<=N;i++){if(in[i]<=1){Q.push({i,0});dis[i]=0;}S[i].insert(Inf);S[i].insert(Inf);}while(!Q.empty()){auto u=Q.top();Q.pop();if(vis[u.x]) continue;vis[u.x]=1;for(int i=head[u.x];~i;i=edge[i].next){S[edge[i].to].insert(dis[u.x]+edge[i].w);if(dis[edge[i].to]>get(edge[i].to)){dis[edge[i].to]=get(edge[i].to);if(!vis[edge[i].to]) Q.push({edge[i].to,dis[edge[i].to]});}}}
}
void solve(){cin>>N;G_init();for(int i=1;i<=N-1;i++){cin>>u>>v>>w;add(u,v,w);add(v,u,w);in[u]++;in[v]++;}dij();for(int i=1;i<=N;i++){if(dis[i]==Inf) cout<<-1<<" \n"[i==N];else cout<<dis[i]<<" \n"[i==N];}
}
signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int __=1;//cin>>__;while(__--)solve();return 0;
}