Description
Input
* 第一行: 两个空格分开的数, N和M
* 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i
Output
* 第1..N-1行: 第i行包含一个数:从牛棚_1到牛棚_i+1并且避免从牛棚1到牛棚i+1最短路经上最后一条牛路的最少的时间.如果这样的路经不存在,输出-1.
Sample Input
4 5
1 2 2
1 3 2
3 4 4
3 2 1
2 4 3
输入解释:
跟题中例子相同
Sample Output
3
3
6
输出解释:
跟题中例子相同
HINT
Source
Gold
//啊哈哈哈哈 我的 树剖又回来了 inline似乎并没有什么软用 亲测
//有的确实变快了 有的却变慢了
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 2e5+10 ;
const int MAXM = 4e5+10 ;
#define INF 0x3f3f3f3f
struct Edge{ int u,next,w,v;bool o; }e[MAXM];//边表
int head[MAXN],tot=1;
inline void Add_Edge(int u,int v,int w){
e[++tot].u=u;e[tot].v=v;e[tot].w=w;
e[tot].next=head[u];head[u]=tot;
}
typedef pair<int,int>Pair;
priority_queuevector,greater >q;
int visx,vis[MAXN],dep[MAXN],dis[MAXN],siz[MAXN],son[MAXN],fa[MAXN],top[MAXN],n,m;
int p[MAXN],pos[MAXN],w[MAXN];
struct Tree{ int l,r,mn,tag,u; }tre[MAXN<<1];//线段树
inline void PushDown(int now){
if(tre[now].tag==INF) return;
int lc=now<<1,rc=now<<1|1;
tre[lc].tag=min(tre[now].tag,tre[lc].tag);
tre[rc].tag=min(tre[now].tag,tre[rc].tag);
tre[lc].mn=min(tre[lc].mn,tre[now].tag);
tre[rc].mn=min(tre[rc].mn,tre[now].tag);
}
inline void Dijkstra(){
memset(dis,0x3f,sizeof dis );
dis[1]=0;q.push(make_pair(0,1));
while(!q.empty()){
int u=q.top().second;q.pop();
if(vis[u]) continue;vis[u]=1;
for(int i=head[u];i;i=e[i].next){
int v=e[i].v;
if(dis[v]>dis[u]+e[i].w){
dis[v]=dis[u]+e[i].w;
e[i].o=1; e[p[v]].o=0; p[v]=i;
q.push(make_pair(dis[v],v));
}
}
}
}
inline void DFS_1(int u,int father,int deepth){
siz[u]=1;dep[u]=deepth;fa[u]=father;
for(int i=head[u];i;i=e[i].next){
int v=e[i].v;
if(v!=father&&e[i].o&&v!=son[u]){
DFS_1(v,u,deepth+1);
siz[u]+=siz[v];
if(siz[son[u]]inline void DFS_2(int u,int Top){
top[u]=Top;w[pos[u]= ++visx]=u;
if(son[u]) DFS_2(son[u],Top);
for(int i=head[u];i;i=e[i].next){
int v=e[i].v;
if(e[i].o&&v!=fa[u]&&v!=son[u]) DFS_2(v,v);//
}
}
inline void Built(int u,int l,int r){
tre[u].l=l;tre[u].r=r;tre[u].mn=tre[u].tag=INF;
if(l==r) return ;
int mid=(l+r)>>1;
Built(u<<1,l,mid);
Built(u<<1|1,mid+1,r);
}
inline int Get_LCA(int u,int v){
while(top[u]!=top[v]){
if(dep[top[u]]if(dep[u]>dep[v]) swap(u,v);
return u;
}
inline void UpDate(int u,int L,int R,int x){
if(L==tre[u].l&&tre[u].r==R){
tre[u].tag=min(tre[u].tag,x);
if(L==R) tre[u].mn=min(x,tre[u].mn);
return;
}
PushDown(u);
int mid=(tre[u].l+tre[u].r)>>1;
if(R<=mid) UpDate(u<<1,L,R,x);
else if(L>mid) UpDate(u<<1|1,L,R,x);
else UpDate(u<<1,L,mid,x),UpDate(u<<1|1,mid+1,R,x);
}
inline void modify(int x,int lca,int val){
int fx=top[x];
while(dep[fx]>dep[lca]){
UpDate(1,pos[fx],pos[x],val);
x=fa[fx],fx=top[x];
}
if(x!=lca) UpDate(1,pos[lca]+1,pos[x],val);
}
inline int Query(int u,int x){
if(tre[u].l==tre[u].r) return tre[u].mn;
PushDown(u);
int mid=(tre[u].l+tre[u].r)>>1;
if(x<=mid) return Query(u<<1,x);
else return Query(u<<1|1,x);
}
inline int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c-'0');c=getchar();}
return x*f;
}
int main(){
//scanf("%d%d",&n,&m);
n=read();m=read();
for(int u,v,w,i=1;i<=m;i++){
u=read();v=read();w=read();
//scanf("%d%d%d",&u,&v,&w);
Add_Edge(u,v,w);Add_Edge(v,u,w);
}
Dijkstra();
DFS_1(1,0,1);
DFS_2(1,1);
Built(1,1,visx);
for(int i=1;i<=tot;i++){//双向边
if(!e[i].o){
int u=e[i].u,v=e[i].v,w=e[i].w;
int LCA=Get_LCA(u,v);
modify(v,LCA,dis[u]+dis[v]+e[i].w);
}
}
for(int i=2;i<=n;i++){
int x=Query(1,pos[i]);
if(x==INF) puts("-1");
else printf("%d\n",x-dis[i]);
}
return 0;
}
//不知为何 T的很惨 也许是我把题做难了
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 2e5+10 ;
const int MAXM = 4e5+10 ;
const int INF = 1e9;
struct Edge{ int u,next,w,v;bool o; }e[MAXM];//边表
int head[MAXN],tot=1;
inline void Add_Edge(int u,int v,int w){
e[++tot].u=u;e[tot].v=v;e[tot].w=w;
e[tot].next=head[u];head[u]=tot;
}
struct Node{//堆优化的Dij
int index,dis;
bool operator < (const Node &a) const {
return dis > a.dis;
}
};
priority_queue q;
int visx,vis[MAXN],dep[MAXN],dis[MAXN],siz[MAXN],son[MAXN],fa
[MAXN],top[MAXN],n,m;
int p[MAXN],pos[MAXN];
struct Tree{
int l,r,mn,tag,u;
void minv(int x);
void PushDown();
void maintain();
}tre[MAXN<<1];//线段树
inline void Tree::minv(int x){ tag=x;mn=min(mn,x); }
inline void Tree::PushDown(){
if(tag!=-1&&l!=r){
tre[u<<1].minv(tag);
tre[u<<1|1].minv(tag);
tag=-1;
}
}
inline void Tree::maintain(){
if(l==r) return ;
mn=min(tre[u<<1].mn,tre[u<<1|1].mn);
}
inline void Dijkstra(){
for(int i=0;i<=n;i++) dis[i]=INF;
dis[1]=0;q.push(Node{1,0});
while(!q.empty()){
int u=q.top().index;q.pop();
if(vis[u]) continue;vis[u]=1;
for(int i=head[u];i;i=e[i].next){
int v=e[i].v;
if(dis[v]>dis[u]+e[i].w){
dis[v]=dis[u]+e[i].w;
mark[p[v]]=0;mark[i]=1;p[v]=i;
q.push(Node{v,dis[v]});
}
}
}
}
inline void DFS_1(int u,int father,int deepth){
siz[u]=1;dep[u]=deepth;fa[u]=father;son[u]=0;
for(int i=head[u];i;i=e[i].next){
if(mark[i]){
int v=e[i].v;
if(v!=father){
DFS_1(v,u,deepth+1);
siz[u]+=siz[v];
if(siz[son[u]]inline void DFS_2(int u,int Top){
top[u]=Top;pos[u]= ++visx;
if(son[u]) DFS_2(son[u],Top);
for(int i=head[u];i;i=e[i].next){
int v=e[i].v;
if(e[i].o&&v!=fa[u]&&v!=son[u]) DFS_2(v,v);//
}
}
inline void Built(int u,int l,int r){
tre[u].u=u;
tre[u].l=l;tre[u].r=r;tre[u].mn=INF;tre[u].tag=-1;
if(l==r) return ;
int mid=(l+r)>>1;
Built(u<<1,l,mid);
Built(u<<1|1,mid+1,r);
}
inline int Get_LCA(int u,int v){
while(top[u]!=top[v]){
if(dep[top[u]]return dep[u]inline void UpDate(int u,int L,int R,int x){
tre[u].PushDown();
if(L<=tre[u].l&&tre[u].r<=R) tre[u].minv(x);
else {
int mid=(tre[u].l+tre[u].r)>>1;
if(L<=mid) UpDate(u<<1,L,R,x);
if(mid1|1,L,R,x);
tre[u].maintain();
}
}
inline int Query(int u,int x){
tre[u].PushDown();
if(tre[u].l==tre[u].r) return tre[u].mn;
else {
int mid=(tre[u].l+tre[u].r)>>1;
if(x<=mid) return Query(u<<1,x);
else return Query(u<<1|1,x);
}
}
inline void Modify(int u,int v,int x){
while(top[u]!=top[v]){
if(dep[top[u]]1,pos[top[u]],pos[u],x);
u=fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
UpDate(1,pos[u],pos[v],x);
}
inline int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c-'0');c=getchar();}
return x*f;
}
int main(){
n=read();m=read();
for(int u,v,w,i=1;i<=m;i++){
u=read();v=read();w=read();
Add_Edge(u,v,w);Add_Edge(v,u,w);
}
Dijkstra();
DFS_1(1,0,1);
DFS_2(1,1);
Built(1,1,visx);
for(int i=2;i<=tot;i+=2){//双向边
int u=e[i].u,v=e[i].v,w=e[i].w;
int LCA=Get_LCA(u,v);
if(!mark[i]) Modify(v,LCA,dis[u]+dis[v]+e[i].w);
if(!mark[i^1]) Modify(u,LCA,dis[u]+dis[v]+e[i].w);
}
for(int i=2;i<=n;i++){
int w=Query(1,pos[i]);
if(w==INF) printf("%d\n",-1);
else printf("%d\n",w-dis[i]);
}
return 0;
}
//硬生生没看出是用并查集、、不过树剖+线段树有A的
//没时间了、、还要交作业
#include
#include
#include
#include
#include
#define maxn 500010
using namespace std;
int n, m;
struct Edge{int to,next,dis;};
Edge G[maxn],edge[maxn];
int h[maxn],cnt;
void add(int u,int v,int d){
edge[++cnt].to=v;edge[cnt].dis=d;
edge[cnt].next=h[u];h[u]=cnt;
}
priority_queueint, int> >Q;
int dis[maxn],Count;
bool vis[maxn<<1];
struct Edge_{
int u,v,d;
bool operator<(const Edge_& k)const{
return dis[u] + dis[v] + d < dis[k.u] + dis[k.v] + k.d;
}
}test[maxn];
namespace Dijkstra{
int h[maxn], cnt = 1;
void addG(int u,int v,int d){
G[++cnt].to=v;G[cnt].dis=d;
G[cnt].next=h[u];h[u]=cnt;
}
void work(){
int u,v,d;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&d);
addG(u,v,d),addG(v,u,d);
}
Q.push(make_pair(0,1));
memset(dis,0x7f,sizeof dis);
dis[1]=0;
while(!Q.empty()){
int u = Q.top().second;
Q.pop();if(vis[u])continue;
vis[u]=true;
for(int i=h[u];i;i=G[i].next){
int v=G[i].to;
if(vis[v])continue;
if(dis[v]>dis[u]+G[i].dis){
dis[v]=dis[u]+G[i].dis;
Q.push(make_pair(-dis[v],v));
}
}
}
memset(vis,0,sizeof vis);
for(int i=1;i<=n;i++)
for(int j=h[i];j;j=G[j].next){
if(vis[j^1])continue;
int v=G[j].to;
if(dis[v]==dis[i]+G[j].dis)
add(i,v,G[j].dis);
else if(dis[i]==dis[v]+G[j].dis)
add(v,i,G[j].dis);
else{
Count ++;
test[Count].u=i;
test[Count].v=v;
test[Count].d=G[j].dis;
}vis[j]=true;
}
sort(test+1,test+1+Count);
}
}
int fa[maxn],dep[maxn];
void dfs(int u){
dep[u]=dep[fa[u]]+1;
for(int i=h[u];i;i=edge[i].next){
int v=edge[i].to;
fa[v]=u;
dfs(v);
}
}
int par[maxn];
int getfa(int x){return x == par[x] ? x : par[x] = getfa(par[x]);}
int ans[maxn];
void Union(int u,int v,int d){
int i=getfa(u),j=getfa(v);
while(i!=j){
if(dep[i]int main(){
scanf("%d%d",&n,&m);
Dijkstra::work();
for(int i=1;i<=n;i++) par[i]=i;
dfs(1);
memset(ans,-1,sizeof ans);
for(int i=1;i<=Count;i++) Union(test[i].u,test[i].v,test[i].d);
for(int i=2;i<=n;i++)
if(~ans[i])printf("%d\n",ans[i]);
else printf("-1\n");
return 0;
}