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
输出解释:
跟题中例子相同

解题思路:

先建出来最短路树(题目都提示到这个份上了)

然后考虑不走最后一条边那么就要从子节点走或者从一些其他非树边走。

可以证明最后只经过一条非树边

考虑非树边可以怎么走。

一条非树边可以造成的贡献就是其Lca到这两个点上的所有树边。

其答案就是ansx=disu+disv+lenu-v-disx

disx一定那么可以将disu+disv+lenu-v插入树链

最后求最小值就好了。

可以用树链剖分实现。

代码:

 #include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
const int N=;
int tr[N<<];
struct pnt{
int hd;
int no;
int fa;
int tp;
int dp;
int dis;
int ind;
int wgt;
int mxs;
bool vis;
bool friend operator < (pnt x,pnt y)
{
return x.dis>y.dis;
}
}p[N];
struct ent{
int twd;
int lst;
int vls;
bool use;
}e[N<<];
std::priority_queue<pnt>Q;
/*class priority_queue{
public:
void push(pnt x)
{
line[++siz]=x;
int nw=siz;
while((nw>>1))
{
int nx=nw>>1;
if(line[nx].dis<line[nw].dis)
break;
std::swap(line[nw],line[nx]);
nw=nx;
}
return ;
}
void pop(void)
{
line[1]=line[siz--];
int nw=1;
while((nw<<1)<=siz)
{
int nx=nw<<1;
if(nx<siz&&line[nx].dis>line[nx+1].dis)
nx++;
if(line[nw].dis<line[nx].dis)
break;
std::swap(line[nw],line[nx]);
nw=nx;
}
return ;
}
int top(void)
{
return line[1].no;
}
bool empty(void)
{
return siz==0;
}
private:
pnt line[N];
int siz;
}Q;*/
int n,m;
int cnt;
int dfn;
void ade(int f,int t,int v)
{
cnt++;
e[cnt].twd=t;
e[cnt].lst=p[f].hd;
e[cnt].vls=v;
p[f].hd=cnt;
return ;
}
void Dij(int x)
{
for(int i=;i<=n;i++)
{
p[i].no=i;
p[i].dis=0x3f3f3f3f;
}
p[].dis=;
p[].fa=;
Q.push(p[x]);
while(!Q.empty())
{
x=Q.top().no;
Q.pop();
if(p[x].vis)
continue;
p[x].vis=true;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].dis>p[x].dis+e[i].vls)
{
p[to].fa=x;
p[to].dis=p[x].dis+e[i].vls;
Q.push(p[to]);
}
}
}
return ;
}
void Basic_dfs(int x,int f)
{
p[x].dp=p[f].dp+;
p[x].wgt=;
int maxs=-;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].fa!=x||to==f)
{
e[i].use=true;
continue;
}
Basic_dfs(to,x);
p[x].wgt+=p[to].wgt;
if(maxs<p[to].wgt)
{
p[x].mxs=to;
maxs=p[to].wgt;
}
}
return ;
}
void Build_dfs(int x,int top)
{
if(!x)
return ;
p[x].tp=top;
p[x].ind=++dfn;
Build_dfs(p[x].mxs,top);
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].fa!=x||p[to].ind)
continue;
Build_dfs(to,to);
}
return ;
}
int Lca(int x,int y)
{
while(p[x].tp!=p[y].tp)
{
if(p[p[x].tp].dp<p[p[y].tp].dp)
std::swap(x,y);
x=p[p[x].tp].fa;
}
if(p[x].dp>p[y].dp)
std::swap(x,y);
return x;
}
void update(int l,int r,int ll,int rr,int spc,int v)
{
if(l>rr||ll>r)
return ;
if(ll<=l&&r<=rr)
{
tr[spc]=std::min(tr[spc],v);
return ;
}
int mid=(l+r)>>;
update(l,mid,ll,rr,spc<<,v);
update(mid+,r,ll,rr,spc<<|,v);
return ;
}
int query(int l,int r,int pos,int spc)
{
if(l==r)
return tr[spc];
int ans=tr[spc];
int mid=(l+r)>>;
if(pos<=mid)
return std::min(query(l,mid,pos,spc<<),ans);
else
return std::min(query(mid+,r,pos,spc<<|),ans);
}
int main()
{
memset(tr,0x6f,sizeof(tr));
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
ade(a,b,c);
ade(b,a,c);
}
Dij();
Basic_dfs(,);
Build_dfs(,);
for(int i=;i<=cnt;i+=)
{
int x,y;
x=e[i].twd;
y=e[i+].twd;
int val=e[i].vls+p[x].dis+p[y].dis;
int z=Lca(x,y);
if(e[i].use)
{
while(p[x].tp!=p[z].tp)
{
update(,dfn,p[p[x].tp].ind,p[x].ind,,val);
x=p[p[x].tp].fa;
}
if(x!=z)
update(,dfn,p[z].ind+,p[x].ind,,val);
}
if(e[i+].use)
{
while(p[y].tp!=p[z].tp)
{
update(,dfn,p[p[y].tp].ind,p[y].ind,,val);
y=p[p[y].tp].fa;
}
if(y!=z)
update(,dfn,p[z].ind+,p[y].ind,,val);
}
}
for(int i=;i<=n;i++)
{
int ans=0x3f3f3f3f;
ans=std::min(ans,query(,dfn,p[i].ind,)-p[i].dis);
if(ans==0x3f3f3f3f)
ans=-;
printf("%d\n",ans);
}
return ;
}

BZOJ1576: [Usaco2009 Jan]安全路经Travel(树链剖分)的更多相关文章

  1. bzoj 1576: [Usaco2009 Jan]安全路经Travel 树链剖分

    1576: [Usaco2009 Jan]安全路经Travel Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 665  Solved: 227[Sub ...

  2. 【思维题 并查集 图论】bzoj1576: [Usaco2009 Jan]安全路经Travel

    有趣的思考题 Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i Output * 第1..N-1行: 第 ...

  3. [BZOJ1576] [Usaco2009 Jan]安全路经Travel(堆优化dijk + (并查集 || 树剖))

    传送门 蒟蒻我原本还想着跑两边spfa,发现不行,就gg了. 首先这道题卡spfa,所以需要用堆优化的dijkstra求出最短路径 因为题目中说了,保证最短路径有且只有一条,所以可以通过dfs求出最短 ...

  4. BZOJ1576 [Usaco2009 Jan]安全路经Travel

    首先用Dijkstra做出最短路生成树,设dis[p]为1到p点的最短路长度 对于一条不在生成树上的边u -> v,不妨设fa为u.v的lca 则一fa到v的路径上的任意点x都可以由u达到,走的 ...

  5. BZOJ1576: [Usaco2009 Jan]安全路经Travel(最短路 并查集)

    题意 给你一张无向图,保证从1号点到每个点的最短路唯一.对于每个点求出删掉号点到它的最短路上的最后一条边(就是这条路径上与他自己相连的那条边)后1号点到它的最短路的长度 Sol emmm,考场上想了个 ...

  6. 【BZOJ1576】[Usaco2009 Jan]安全路经Travel 最短路+并查集

    [BZOJ1576][Usaco2009 Jan]安全路经Travel Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, ...

  7. [BZOJ1576] [BZOJ3694] [USACO2009Jan] 安全路径(最短路径+树链剖分)

    [BZOJ1576] [BZOJ3694] [USACO2009Jan] 安全路径(最短路径+树链剖分) 题面 BZOJ1576和BZOJ3694几乎一模一样,只是BZOJ3694直接给出了最短路树 ...

  8. bzoj 1576 [Usaco2009 Jan]安全路经Travel(树链剖分,线段树)

    [题意] 给定一个无向图,找到1-i所有的次短路经,要求与最短路径的最后一条边不重叠. [思路] 首先用dijkstra算法构造以1为根的最短路树. 将一条无向边看作两条有向边,考察一条不在最短路树上 ...

  9. [BZOJ 1576] [Usaco2009 Jan] 安全路经Travel 【树链剖分】

    题目链接: BZOJ - 1576 题目分析 首先Orz Hzwer的题解. 先使用 dijikstra 求出最短路径树. 那么对于一条不在最短路径树上的边 (u -> v, w) 我们可以先沿 ...

随机推荐

  1. Android 6.0 执行时权限处理全然解析

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/50709663: 本文出自:[张鸿洋的博客] 一.概述 随着Android 6. ...

  2. html5缓存

    HTML5 提供了两种在client存储数据的新方法: localStorage - 没有时间限制的数据存储 sessionStorage - 针对一个 session 的数据存储 这些都是由 coo ...

  3. Linux Sendfile 的优势

    Sendfile 函数在两个文件描写叙述符之间直接传递数据(全然在内核中操作,传送),从而避免了内核缓冲区数据和用户缓冲区数据之间的拷贝,操作效率非常高,被称之为零拷贝. Sendfile 函数的定义 ...

  4. Hadoop2.2集群安装配置-Spark集群安装部署

    配置安装Hadoop2.2.0 部署spark 1.0的流程 一.环境描写叙述 本实验在一台Windows7-64下安装Vmware.在Vmware里安装两虚拟机分别例如以下 主机名spark1(19 ...

  5. Runtime类中的freeMemory,totalMemory,maxMemory等几个方法

    最近在网上看到一些人讨论到Java.lang.Runtime类中的freeMemory(),totalMemory(),maxMemory ()这几个方法的一些题目,很多人感到很迷惑,为什么,在jav ...

  6. BZOJ5106: [CodePlus2017]汀博尔

    [传送门:BZOJ5106] 简要题意: 给出n棵树,初始高度为h[i],每棵树每个月长高a[i] 现有一个客户,需要至少s长的总木材,而且每次截取的木材必须是一整颗树而且高度大于等于L 求出最少的月 ...

  7. js易错点总结及 常见面试的坑

    最近在研究Javascript发现了其中一些比较灵异的事情.有点让人感到无语比如: var arr = [], arr2 = {}; console.log(typeof(arr) === typeo ...

  8. 洛谷P1586 四方定理

    题目描述 四方定理是众所周知的:任意一个正整数nn ,可以分解为不超过四个整数的平方和.例如:25=1^{2}+2^{2}+2^{2}+4^{2}25=12+22+22+42 ,当然还有其他的分解方案 ...

  9. 打包,VS 之 InstallShield Limited Edition for Visual Studio 2015 图文教程

    转载收藏于 https://www.cnblogs.com/xinaixia/p/5473815.html 从Visual Studio 2012开始,微软就把自家原来的安装与部署工具彻底废掉了,转而 ...

  10. js实现日期转换方法

    //方法1function timeStamp1String(time) { var datetime = new Date(); datetime.setTime(time); var year = ...