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