USACO 2009 January Gold 安全路径

限时加码!20+主流AI编程工具免费用 购周边加赠Coding Plan Lite,Claude Code、Cursor等即刻畅享,学习进阶更高效! 阅读详情

Description

Gremlins最近在农场上泛滥,它们经常会阻止牛们从农庄(牛棚_1)走到别的牛棚(牛_i的目的地是牛棚_i)。每一个gremlin只认识牛_i并且知道牛_i一般走到牛棚_i的最短路经。所以它们在牛_i到牛棚_i之前的最后一条牛路上等牛_i,当然,牛不愿意遇到Gremlins,所以准备找一条稍微不同的路经从牛棚_1走到牛棚_i,所以,请你为每一头牛_i找出避免gremlin_i的最短路经的长度。
  和以往一样,农场上的M (2 <= M <= 200,000)条双向牛路编号为1..M并且能让所有牛到达它们的目的地,N(3 <= N <= 100,000)个编号为1..N的牛棚。牛路i连接牛棚a_i (1 <= a_i <= N)和b_i (1 <= b_i <= N)并且需要时间t_i (1 <=t_i <= 1,000)通过。没有两条牛路连接同样的牛棚,所有牛路满足a_i!=b_i。在所有数据中,牛_i使用的牛棚_1到牛棚_i的最短路经是唯一的。

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

【数据范围】
20%的数据满足,N<=200;
50%的数据满足,N<=3000
100%的数据满足,N<=100,000

做这道题之前还不知道有最短路径树这个东西。。。(太菜了233)

既然最短路径是唯一的,显然符合树的性质(可以用反证法证最短路性质)。

题目大意:生成最短路径树后,每次fa[x]->x这条边,用剩余所有边来求1->x的最短路径。

发现是个树,首先就想到树剖。。。

对于一个节点x,有ans=min{dist[u]+dist[v]+w(u,v)-dist[x]},x在lca(u,v)之下,在u,v之上(画图),事实上,也只有满足条件的这种x会被更新到:

1、x在v下面,根据最短路径树的性质,dist[u]+w(u,v)+(v->x)>dist[x]所以不会被更新

2、x在u下面,同上

3、x在lca(u,v)上面,显然= =

发现这个性质之后,就是树剖乱搞了。需要注意的是,u,v会被更新,但lca(u,v)不能被更新。

(码了一个晚自习。。。心力憔悴。。。感动。。。)

#include<bits/stdc++.h>
using namespace std;
#define Inc(i,L,r) for(register int i=(L);i<=(r);++i)
#define Red(i,r,L) for(register int i=(r);i>=(L);--i)
const int N = 1e5+10,E = 2e5+10;
struct Edge{
	int cnt,h[N],w[E<<1],fr[E<<1],to[E<<1],next[E<<1];
	inline void add(int x,int y,int z){
		next[++cnt]=h[x],h[x]=cnt;
		fr[cnt]=x,to[cnt]=y;
		w[cnt]=z;
	}
}e,ex;
bool intree[E<<1];
int n,m;
struct Djkstra{
	struct Node{
		int idx,dist;
		bool operator <(const Node&A) const {
			return dist>A.dist;
		}
	};int fa[N],id[N],dist[N];
	inline void djkstra(){
		memset(dist,63,sizeof(dist));
		priority_queue<Node>Q;
		Q.push((Node){1,dist[1]=0});
		while(!Q.empty()){
			Node x=Q.top();Q.pop();
			for(int p=e.h[x.idx];p;p=e.next[p]){
				int to=e.to[p];if(dist[to]>dist[x.idx]+e.w[p]){
					id[to]=p,fa[to]=x.idx;
					Q.push((Node){to,dist[to]=dist[x.idx]+e.w[p]});
				}
			}
		}
	}
	inline void init(){
		scanf("%d%d",&n,&m);
		e.cnt=1;
		Inc(i,1,m){
			int x,y,z;scanf("%d%d%d",&x,&y,&z);
			e.add(x,y,z),e.add(y,x,z);
		}
	}
}djk;
struct Graph{
	int p[N][18];
	inline void init(){
		Inc(i,1,n)siz[i]=1;
		memset(p,-1,sizeof(p));
		Inc(i,2,n)ex.add(djk.fa[i],i,0);
		Inc(i,2,n)intree[djk.id[i]]=intree[djk.id[i]^1]=1;//树边
	}
	int siz[N],son[N],dep[N];
	int cnt,dfn[N],top[N];
	inline void dfs1(int x,int Fa,int depth){
		for(int P=ex.h[x];P;P=ex.next[P]){
			dfs1(ex.to[P],p[ex.to[P]][0]=x,dep[ex.to[P]]=depth+1);
			siz[x]+=siz[ex.to[P]];
			if(siz[son[x]]<siz[ex.to[P]])son[x]=ex.to[P];
		}
	}
	inline void dfs2(int x,int sp){
		dfn[x]=++cnt;top[x]=sp;
		if(son[x])dfs2(son[x],sp);
		for(int P=ex.h[x];P;P=ex.next[P])if((ex.to[P]^p[x][0])&&(ex.to[P]^son[x]))dfs2(ex.to[P],ex.to[P]);
	}
	inline void ST(){
		int maxdep=log2(n);
		Inc(j,1,maxdep)
			Inc(i,1,n)if(~p[i][j-1])p[i][j]=p[p[i][j-1]][j-1];
	}
	inline int lca(int x,int y){
		if(dep[x]<dep[y])swap(x,y);
		Red(i,log2(dep[x]),0)if(dep[x]-(1<<i)>=dep[y])x=p[x][i];
		if(x==y)return y;
		Red(i,log2(dep[x]),0)if(p[x][i]^p[y][i])x=p[x][i],y=p[y][i];
		return p[x][0];
	}
}g;
struct SegMent{
	struct tree{
		int L,r,mn;
	}t[N<<2];
	#define Ls v<<1
	#define rs v<<1|1
	inline void pushdown(int v){
		t[Ls].mn=min(t[Ls].mn,t[v].mn);
		t[rs].mn=min(t[rs].mn,t[v].mn);
	}
	inline int query(int v,int x){
		if(t[v].L>x||t[v].r<x)return 1<<30;
		if(t[v].L==t[v].r)return t[v].mn;
		pushdown(v);
		return min(query(Ls,x),query(rs,x));
	}
	inline void update(int v,int A,int b,int k){
		if(t[v].L>b||t[v].r<A)return ;
		if(A<=t[v].L&&t[v].r<=b)return t[v].mn=min(t[v].mn,k),void();
		pushdown(v);
		update(Ls,A,b,k),update(rs,A,b,k);
	}
	inline void build(int v,int L,int r){
		t[v]=(tree){L,r,1<<30};
		if(L==r)return ;
		int Mid=L+r>>1;
		build(Ls,L,Mid),build(rs,Mid+1,r);
	}
}t;
inline void modify(int x,int lca,int val){
	int tx=g.top[x];
	while(tx^g.top[lca]){
		t.update(1,g.dfn[tx],g.dfn[x],val);
		x=g.p[tx][0],tx=g.top[x];
	}
	t.update(1,g.dfn[lca]+1,g.dfn[x],val);
}
inline void solv(){
	t.build(1,1,n);
	Inc(i,2,e.cnt)if(!intree[i]){
		int x=e.fr[i],y=e.to[i],lca=g.lca(x,y);
		modify(x,lca,djk.dist[x]+djk.dist[y]+e.w[i]);
		modify(y,lca,djk.dist[x]+djk.dist[y]+e.w[i]);
	}
	Inc(i,2,n){
		int dist=t.query(1,g.dfn[i]);
		cout<<(dist==1<<30?-1:dist-djk.dist[i])<<"\n";
	}
}
int main(){
	djk.init();
	djk.djkstra();
	g.init();
	g.dfs1(1,0,0);
	g.dfs2(1,1);
	g.ST();
	solv();
	return 0;
}

 

USACO 2006 November Gold Corn Fields USACO 2006 November Gold Corn Fields 题目描述: Farmer John has purchased a lush new rectangular pasture composed of M by N square parcels. He wants to grow some yummy corn for the cows on a number of sq... 阅读详情

相关推荐

USACO JAN 09】安全路径(Dijkstra+线段树合并)

Gremlins——“小魔怪”,这么可爱的名字怎么不译出来?

AFO 539

USACO 2009 JAN GOLD安全路径

题目 问题描述 Gremlins最近在农场上泛滥,它们经常会阻止牛们从农庄(牛棚_1)走到别的牛棚(牛_i的目的地是牛棚_i)。每一个gremlin只认识牛_i并且知道牛_i一般走到牛棚_i的最短路经。所以它们在牛_i到牛棚_i之前的最后一条牛路上等牛_i,当然,牛不愿意遇到Gremlins,所以准备找一条稍微不同的路经从牛棚_1走到牛棚_i,所以,请你为每一头牛_i找出避免gremlin_i的最短路经的长度。 和以往一样,农场上的M (2 <= M <= 200,000)条双向牛路编号为1

weixin_43823476的博客 446

USACO 2012 January Contest, Bronze Division

在达尔的指导下,第一次做了这类比赛, 在 Observers 里面的成绩: CHN Chuanshun Yuan 833 * * * * * * * * x * * * * * * * * * * * * x x x * x * * * * 排了30+,被达尔戈

坐井观天 1657

USACO安全路径(计数/求和以及最值小探讨)(最有生成树之最短路径树,LCA,最值问题,并查集)

题目【问题描述】   精灵最近在农场上泛滥,他们经常会阻止牛们从农庄(牛棚1)走到别的牛棚(牛i的目的地是牛棚i)。每一个精灵只认识牛i并且知道牛i一般走到牛棚i的最短路径。所以他们在牛i到牛棚i之间的最后一条牛路上等牛i。当然,牛不愿意遇到精灵,所以准备找一条稍微不同的路径从牛棚1走到牛棚i。请你为每一头牛i找出避免精灵的最短路径长度。   和往常一样,农场上有 n 个牛棚(编号为1..n),

少主大人殿下的博客 679

[USACO Jan09]安全路径Safe Travel解题报告

题目 http://cojs.tk/cogs/problem/problem.php?pid=279 分析 首先把最短路径树画出来(由题意最短路径唯一,所以是树): 其中1是根。我们将树记作T,i的子树记作B。图中,B是绿色点,T-B是红色点。 而1~i最短路上的最后一条边(也就是不能走的边)即i的父亲边。将这条边去掉以后,1~i的最短路长什么

uKJLThHU$(eQ 2102

[JZOJ1320] 【Usaco2009 gold 】拯救奶牛

题目 题目大意 一个三角形的网格图,三角形与其有共同边的三角形相连。 起点到所有终点的最短距离。 思考历程 数据看起来还挺大的,所以不是什么图论算法。 这显然是一个结论题。 什么结论? 然后我就开始推: 一个点(x,y)(x,y)(x,y),它可以到达(x,y−1)(x,y+1)(x,y-1)(x,y+1)(x,y−1)(x,y+1)。 如果yyy是奇数,那么可以到达(x+1,y+1)(x...

A1847225889的博客 259

Roping the Field·动规

Roping the Field题目信息输入输出测试样例提示来源解答 题目信息 Farmer John is quite the nature artist: he often constructs large works of art on his farm. Today, FJ wants to construct a giant “field web”. FJ’s field is large convex polygon with fences along the boundary and fenc

zhj12399的博客 456

【组队赛#9】USACO 2006 January Bronze

【A题】A. Stump Removal 链接click here~~ 【题目大意】一排高低不平的树桩,需要用炸弹全部炸掉,如果一个树桩的前面和后面的树桩高度都比它小,炸弹爆炸的时候会同时炸掉,求尽可能少的放置炸弹的数目,输出树桩的编号。 【解题思路】 理解题意,从左往右扫,如果当前位置右边或左边的比它低了或相等,那么就把这个位置炸掉,然后把能炸的都炸掉,判断当前树桩前面的和后面的高度比较,

herongwei 的 BLOG 1202

Usaco2009 gold 】修建道路

题意:求最小生成树思路:把他给你的边当做长度为0,然后根据欧几米的距离连边,并查集搞一搞,就好了程序: type Point=record x,y:longint; w:real; end; const maxn=1000000; maxv=1000; var f,x,y:array [1..maxn] of longint; s:array [1..maxv,1

学习成神之路 448

Usaco2009 gold 】拯救奶牛

Description 贝希被困在一个三角形的迷宫之中。这个迷宫有N行(1 &lt;= N &lt;= 1000000)。比如下图是一个3行的迷宫。      迷宫的第i行有2*i-1个三角形,从左到右分别编号为(i,1)、(i,2)等等。贝希每次可以从一个三角形走到任意一个一个跟当前的三角形有邻边的三角形。比如说,如果她目前处于三角形(3,3),那么,她可以走到三角形(3,2)、(3,4)和(4...

Larry1118的博客 478

[usaco2010_mar_silver]极品飞车

题目 描述 Description chdy 想参加赛车比赛,他的赛车质量是M (1 &amp;amp;lt;= M &amp;amp;lt;= 1,000) ,马力是F (1 &amp;amp;lt;= F &amp;amp;lt;= 1,000,000). 为了提升赛车性能,他可以到加工店添加一些零件。加工店有N(1 &amp;amp;lt;= N &amp;amp;lt;= 10,000)种零件,编号1…N, 每种零件只有一件。 零件P_i 能增加的

MILLOPE的博客 336

USACO 2017 January Contest总结

比赛链接 T1 Balanced Photo 题目链接 题目大意:一个人要给他的一堆牛拍照,每头牛有一个身高且身高互不相同。定义L[i]L[i]L[i]为第iii头牛左边比它高的牛的个数,R[i]R[i]R[i]为第iii头牛右边比它高的牛的个数,定义“不平衡的牛”:它的L[i],R[i]L[i],R[i]L[i],R[i]相差两倍以上,求不平衡的牛的个数。 思路:以下是刚看到题的时候的心...

szh_0808的博客 504

Problem : [Usaco2009 Jan]Best Spot

约翰拥有P(1<=P<=500)个牧场.贝茜特别喜欢其中的F个.所有的牧场 由C(1 < C<=8000)条双向路连接,第i路连接着ai,bi,需要Ti(1<=Ti< 892)单 位时间来通过. 作为一只总想优化自己生活方式的奶牛,贝茜喜欢自己某一天醒来,到达所有那F个她喜欢的 牧场的平均需时最小.那她前一天应该睡在哪个牧场呢?请帮助贝茜找到这个最佳牧场. 此可见,牧场10到所有贝茜喜欢的牧场的平均距离最小,为最佳牧场.

Zhao_Chongyan的博客 352

USACO2016 Jan Bronze 1:Promotion Counting

#include #include int sum[10000],ans[10000],x[100001],y[100001]; int main(){ int n=4,m,k,j,i; for(i=1;i<=4;i++){ scanf("%d%d",&y[i],&x[i]); } for(i=n;i>=2;i--){ sum[i]=x[i]-y[i]+ans[i]; ans[

Free Loop~~~跳动的字节 757

[USACO 2009 Feb Gold] Fair Shuttle (贪心+优先队列)

题目大意:有N个站点的轻轨站,有一个容量为C的列车起点在1号站点,终点在N号站点,有K组牛群,每组数量为Mi(1≤Mi≤N),行程起点和终点分别为Si和Ei(1≤Si&lt;Ei≤N)。计算最多有多少头牛可以搭乘轻轨。 一道经典的贪心题目,每当一头牛上车的时候,如果超载,我们就优先踢出去行程终点比较远的那部分牛 而 踢出哪些行程终点较远的牛 以及 哪些在车上的牛在这站到达了终点,都可以用优先队...

guapisolo的博客 321

JZOJ2137.2017.05.20【usaco2017_Mar Bronze & Silver】C组T5Bovine Genomics

题目描述Farmer John owns N cows with spots and N cows without spots. Having just completed a course in bovine genetics, he is convinced that the spots on his cows are caused by mutations in the bovine geno

路人黑的纸巾 1078

Unity开发必备:一键清理Windows注册表中的PlayerPrefs数据

在Unity游戏开发中,数据持久化是核心需求之一,PlayerPrefs作为轻量级本地存储方案,因其简单易用而被广泛采用。其原理是通过键值对将玩家设置、游戏进度等数据存储在特定位置,在Windows平台上则体现为写入系统注册表。这一机制虽然方便,但在频繁迭代的开发测试中,残留的旧测试数据或不同版本间的数据结构冲突,会引发数据读取异常、测试环境不纯净等问题,直接影响开发效率和版本管理的可靠性。因此,针对PlayerPrefs注册表数据的清理工具,成为提升Unity开发工作流的关键实践。本文聚焦于Unity编辑

510
上一篇: BZOJ3723 Network——Kruskal重构树
下一篇: POJ2104 区间第k大(带修改)
DancingZ
博客等级 码龄9年 10粉丝 137原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值