Codeforces Round #406 (Div. 1) B. Legacy 线段树建图跑最短路

来源:互联网 发布:建筑设计mars软件简介 编辑:程序博客网 时间:2024/06/05 05:50

参考:https://vjudge.net/solution/8563240
博客:http://www.cnblogs.com/qscqesze/p/6651447.html
题目:https://vjudge.net/problem/CodeForces-786B

题意三种操作:1 a b c,在建立权值为c的a->b的单向边2 a b c d,建立a->[b,c]权值为d的单向边3 a b c d,建立[b,c]->a权值为d的单向边。给你一个起点,问你起点到其他点的最短路长度。题解:如果暴力建边的话,显然会有n^2个边。但是我们用线段树去建边就好了,我们依次让所有节点都指向自己区间的l端点和r端点就行了。我相当于预先又建了nlogn个节点,这些虚拟节点代替区间。然后跑dij就好了
#include<bits/stdc++.h>using namespace std;const int maxn = 2e6+7;vector<pair<int,int> >v[maxn];long long dist[maxn],ver[2][maxn];int n,q,ss,tme;set<pair<long long,int> >s;int build(int y,int l,int r,int x){    if(l==r)return ver[x][y]=l;    ver[x][y]=++tme;    int mid=(l+r)/2;    int cl=build(y*2,l,mid,x);    int cr=build(y*2+1,mid+1,r,x);    if(x==0){        v[ver[x][y]].push_back(make_pair(cl,0));        v[ver[x][y]].push_back(make_pair(cr,0));    }else{        v[cl].push_back(make_pair(ver[x][y],0));        v[cr].push_back(make_pair(ver[x][y],0));    }    return ver[x][y];}void update(int x,int l,int r,int ll,int rr,int xx,int w,int z){    if(l>rr||r<ll)return;    if(l>=ll&&r<=rr){        if(z==0)v[xx].push_back(make_pair(ver[z][x],w));        else v[ver[z][x]].push_back(make_pair(xx,w));        return;    }    int mid=(l+r)/2;    update(x*2,l,mid,ll,rr,xx,w,z);    update(x*2+1,mid+1,r,ll,rr,xx,w,z);}int main(){    cin>>n>>q>>ss;    memset(dist,-1,sizeof(dist));    tme=n;    build(1,1,n,0);    build(1,1,n,1);    for(int i=0;i<q;i++){        int t,a,b,c,d;        cin>>t>>a>>b>>c;        if(t==1){            v[a].push_back(make_pair(b,c));        }else{            cin>>d;            update(1,1,n,b,c,a,d,t-2);        }    }    dist[ss]=0;    priority_queue<pair<long long,int> >Q;    Q.push(make_pair(0,ss));    while(!Q.empty()){        int now = Q.top().second;        Q.pop();        for(int i=0;i<v[now].size();i++){            int ve=v[now][i].first;            int co=v[now][i].second;            if(dist[ve]==-1||dist[now]+co<dist[ve]){                dist[ve]=dist[now]+co;                Q.push(make_pair(-dist[ve],ve));            }        }    }    for(int i=1;i<=n;i++)        cout<<dist[i]<<" ";    cout<<endl;}
阅读全文
0 0
原创粉丝点击