[BZOJ1576] [Usaco2009 Jan]安全路经Travel
来源:互联网 发布:光学透镜设计软件 编辑:程序博客网 时间:2024/06/05 13:28
题意
题解
我们暂且称避开最短路最后一条边的路径为“次短路”(不是真正的次短路)。
首先将最短路经过的最后一条边都求出来,这些边将形成一棵以1为根的树。
考虑到达点u的答案。若避开点u与fa[u]中的这条边,那么次短路必然是从点1经过最短路到达某点v,从v经过非树边到达点w,从点w沿着最短路向根的方向找到u(即w为u-子树中的节点)。
如图,图(1)中是一种合法的情况,而图(2)中v与w都在u的子树中,这显然是不合法的。即对于所有的非树边的两个端点,若有且仅有一个端点在u的子树中(包含u)就能更新u的答案。如果这样,每个点u都可以由一个非树边的集合来更新它,如果枚举肯定不能接受。观察一条非树边[v,w]如何更新u的答案:
我们最小化
如果进行堆的合并,优先队列是
代码
/// by ztx/// blog.csdn.net/hzoi_ztx#include <bits/stdc++.h>#define Rep(i,l,r) for(i=(l);i<=(r);i++)#define rep(i,l,r) for(i=(l);i< (r);i++)#define Rev(i,r,l) for(i=(r);i>=(l);i--)#define rev(i,r,l) for(i=(r);i> (l);i--)#define Each(i,v) for(i=v.begin();i!=v.end();i++)#define r(x) read(x)typedef long long ll ;typedef double lf ;int CH , NEG ;template <typename TP>inline void read(TP& ret) { ret = NEG = 0 ; while (CH=getchar() , CH<'!') ; if (CH == '-') NEG = true , CH = getchar() ; while (ret = ret*10+CH-'0' , CH=getchar() , CH>'!') ; if (NEG) ret = -ret ;}struct ltnode { int w, u, v; bool operator < (const ltnode&B) const { return w > B.w; }};struct lt { lt *l, *r; int d; ltnode w; lt(); lt(ltnode w);}*null=new lt();lt::lt() { l=r=null;d=0; }lt::lt(ltnode w): w(w) { l=r=null;d=0; }lt* Init(ltnode x) { return new lt(x); }lt* Merge(lt*u,lt*v) { if (u == null) return v; if (v == null) return u; if (u->w < v->w) std::swap(u,v); u->r = Merge(u->r,v); if (u->l->d < u->r->d) std::swap(u->l,u->r); u->d = u->r->d+1; return u;}void Insert(lt*&u,ltnode x) { u = Merge(u,Init(x)); }ltnode Top(lt*u) { return u->w; }void Pop(lt*&u) { lt*tmp = u; u = Merge(u->l,u->r); delete tmp; }bool Empty(lt*u) { return u == null; }#define kN 100010LL#define kM 200010LL#define infi 0x3f3f3f3fLL#define t(p) to[p]#define l(p) len[p]#define n(p) nxt[p]#define s(u) st[u]int to[kM<<1], len[kM<<1], nxt[kM<<1], st[kN], te = 1;inline void Add(int u,int v,int w) { te++;t(te)=v;l(te)=w;n(te)=s(u);s(u)=te; te++;t(te)=u;l(te)=w;n(te)=s(v);s(v)=te;}int dis[kN], pre[kN];bool inq[kN];std::deque<int>q;inline void spfa() { int u, v, p; memset(dis,0x3f,sizeof dis); q.push_back(1), dis[1] = 0; while (!q.empty()) for (u=q.front(),q.pop_front(),inq[u]=false,p=s(u);p;p=n(p)) if (v=t(p),dis[v]>dis[u]+l(p)) if (dis[v]=dis[u]+l(p),pre[v]=u,!inq[v]) if (inq[v]=true,!q.empty()&&dis[v]<dis[q.front()])q.push_front(v); else q.push_back(v);}int n, m, a[kM], b[kM], t[kM];int ans[kN], fa[kN];std::vector<int>g[kN];lt *h[kN];inline int anc(int u) { return fa[u]?fa[u]=anc(fa[u]):u; }void Union(int u,int v) { if((u=anc(u))!=(v=anc(v)))fa[u]=v; }void dp(int u) { for (int i=g[u].size()-1;i>=0;i--) { dp(g[u][i]); h[u] = Merge(h[u],h[g[u][i]]); Union(u,g[u][i]); } while (!Empty(h[u]) && anc(Top(h[u]).u)==anc(Top(h[u]).v)) Pop(h[u]); if (Empty(h[u])) ans[u] = -1; else ans[u] = Top(h[u]).w-dis[u];}int main() { int i; r(n), r(m); Rep (i,1,m) r(a[i]), r(b[i]), r(t[i]), Add(a[i],b[i],t[i]); spfa(); Rep (i,1,n) g[pre[i]].push_back(i), h[i] = null; Rep (i,1,m) { if (pre[a[i]]==b[i] || pre[b[i]]==a[i]) continue; Insert(h[a[i]],(ltnode){dis[a[i]]+dis[b[i]]+t[i],a[i],b[i]}); Insert(h[b[i]],(ltnode){dis[a[i]]+dis[b[i]]+t[i],a[i],b[i]}); } dp(1); Rep (i,2,n) printf("%d\n", ans[i]); END: getchar(), getchar(); return 0;}
阅读全文
0 0
- 【bzoj1576】[Usaco2009 Jan]安全路经Travel
- BZOJ1576: [Usaco2009 Jan]安全路经Travel
- [bzoj1576] [Usaco2009 Jan]安全路经Travel
- [BZOJ1576] [Usaco2009 Jan]安全路经Travel
- BZOJ1576——[Usaco2009 Jan]安全路经Travel
- BZOJ1576 洛谷P2934 : [Usaco2009 Jan]安全路经Travel
- 【BZOJ1576】[Usaco2009 Jan]安全路经Travel【最短路树】【树链剖分】【线段树】
- 【最短路径树+可并堆/树链剖分】BZOJ1576 [Usaco2009 Jan]安全路经Travel
- 【BZOJ 1576】 [Usaco2009 Jan]安全路经Travel
- bzoj 1576 [Usaco2009 Jan]安全路经Travel
- bzoj 1576[Usaco2009 Jan]安全路经Travel
- 1576: [Usaco2009 Jan]安全路经Travel
- [Usaco2009 Jan]安全路经Travel dijkstra + 并查集
- [BZOJ1576][Usaco2009 Jan]安全路径Travel(堆优化dijkstra+并查集)
- bzoj1576[Usaco2009 Jan]安全路径Travel(堆优化dijkstra+并查集)
- [Usaco2009 Jan]安全路经Travel(最短路树+并查集/树链剖分)
- 1576: [Usaco2009 Jan]安全路经Travel 最短路径树+树链剖分+线段树
- bzoj 1576: [Usaco2009 Jan]安全路经Travel(dijkstra堆优化+并查集)
- 抽奖模型的数学期望
- 通过表单上传图片,并存储到服务器指定目录下
- python基础练习
- bzoj 3790(manacher+树状数组)
- hdu 2090 算菜价
- [BZOJ1576] [Usaco2009 Jan]安全路经Travel
- jdk 源码分析(8)java synchronized和锁lock对比
- 注解
- 程序员面试-数据库 1
- LeetCode 561. Array Partition I
- hdu 2091 空心三角形
- 如何向eclipse中添加数据库驱动文件开发JDBC程序
- 高级数据结构2--并查集
- 八大排序算法之-快速排序 java代码