BZOJ1576 洛谷P2934 : [Usaco2009 Jan]安全路经Travel
来源:互联网 发布:js设置高度 编辑:程序博客网 时间:2024/06/06 02:29
1576: [Usaco2009 Jan]安全路经Travel
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:
非inline:
//啊哈哈哈哈 我的 树剖又回来了 inline似乎并没有什么软用 亲测//有的确实变快了 有的却变慢了#include<iostream>#include<cstring>#include<cstdio>#include<cstdlib>#include<cmath>#include<queue>using namespace std;const int MAXN = 2e5+10 ;const int MAXM = 4e5+10 ;#define INF 0x3f3f3f3fstruct 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_queue<Pair,vector<Pair>,greater<Pair> >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]]<siz[v]) son[u]=v; } }}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]]<dep[top[v]]) swap(u,v); u=fa[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<iostream>#include<cstring>#include<cstdio>#include<cstdlib>#include<cmath>#include<queue>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<Node> 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]]<siz[v]) son[u]=v; } } }}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]]<dep[top[v]]) swap(u,v); u=fa[top[u]]; } return dep[u]<dep[v] ? u : v;}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(mid<R) UpDate(u<<1|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]]<dep[top[v]]) swap(u,v); UpDate(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 <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#define maxn 500010using 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_queue<pair<int, 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]<dep[j]) swap(i,j); ans[i]=dis[u]+dis[v]+d-dis[i]; par[i]=fa[i]; i=getfa(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;}
阅读全文
0 0
- BZOJ1576 洛谷P2934 : [Usaco2009 Jan]安全路经Travel
- 【bzoj1576】[Usaco2009 Jan]安全路经Travel
- BZOJ1576: [Usaco2009 Jan]安全路经Travel
- [bzoj1576] [Usaco2009 Jan]安全路经Travel
- [BZOJ1576] [Usaco2009 Jan]安全路经Travel
- BZOJ1576——[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堆优化+并查集)
- Kotlin笔记(九)异常
- [leetcode]154. Find Minimum in Rotated Sorted Array II
- MySQL使用ALTER TABLE创建索引
- [编程开发]STB image读取学习
- 装果子(二分答案)
- BZOJ1576 洛谷P2934 : [Usaco2009 Jan]安全路经Travel
- POJ 2109 Power of Cryptography 笔记
- C语言程序的内存分配方式
- 五分钟搭建App设置页面_纯代码 + 模型思想(OC)
- JDBC编程
- 51nod 1717 好数
- MySQL删除索引
- Socket.IO(聊天应用程序)
- 高阶篇:5.3)EMC电磁兼容(重构);