codeforces 787D - Legacy 線段樹優化建圖,最短路
阿新 • • 發佈:2019-01-07
題意:
有n個點,q個詢問,
每次詢問有一種操作。
操作1:u→[l,r](即u到l,l+1,l+2,...,r距離均為w)的距離為w;
操作2:[l,r]→u的距離為w
操作3:u到v的距離為w
最終求起點到其他點的最短距離,到達不了輸出-1
題解
線段樹優化建圖+最短路...
不知道這種東西,百度了一下,好像最早的是POI2015的PUS,然後2017/2018的oi也都出過,
還是要見識一下的...
程式碼如下:
#include <bits/stdc++.h> #define endl '\n' #define ll long long #define ull unsigned long long #define fi first #define se second #define mp make_pair #define pii pair<int,int> #define all(x) x.begin(),x.end() #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define rep(ii,a,b) for(int ii=a;ii<=b;++ii) #define per(ii,a,b) for(int ii=b;ii>=a;--ii) #define forn(ii,x) for(int ii=head[x];ii;ii=e[ii].next) #pragma GCC optimize("Ofast") #define show(x) cout<<#x<<"="<<x<<endl #define show2(x,y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl #define show3(x,y,z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl #define show4(w,x,y,z) cout<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl #define show5(v,w,x,y,z) cout<<#v<<" "<<v<<" "<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl #define showa(a,b) cout<<#a<<'['<<b<<"]="<<a[b]<<endl using namespace std; const int maxn=1e6+10,maxm=2e6+10; const int INF=0x3f3f3f3f; const int mod=1e9+7; const double PI=acos(-1.0); //head int casn,n,m,k; int num[maxn]; class graph{ public: struct edge{ int from,to;ll cost; edge(int a,int b,ll c){from=a,to=b,cost=c;} }; vector<vector<edge>> node; int ud=0; graph(int n=maxn,int f=0){node.resize(n+2);ud=f;} void add(int a,int b,int c=1){node[a].emplace_back(a,b,c);if(ud)node[b].emplace_back(b,a,c);} }; class dijkstra{ public: struct road{ int now;ll dis; road(int a,ll b){now=a,dis=b;} bool operator<(const road &rhs)const{return dis>rhs.dis;} }; vector<ll> dis; priority_queue<road>q; ll INF; dijkstra(graph &g,int st){ INF=0x3f3f3f3f3f3f3f3f; dis.resize(g.node.size()+1,INF); q.emplace(st,0); dis[st]=0; while(!q.empty()){ road t=q.top();q.pop(); for(auto e:g.node[t.now]){ ll cost=t.dis+e.cost; if(cost<dis[e.to]){ dis[e.to]=cost; q.emplace(e.to,cost); } } } } }; class segtree{ public: #define nd node[now] #define ndl node[now<<1] #define ndr node[now<<1|1] struct segnode { int l,r;int id; int mid(){return (r+l)>>1;} int len(){return r-l+1;} }; graph *g; int cnt,flag; vector<segnode> node; vector<int> ff; segtree(int n,graph *x,int y,int id) { g=x;cnt=id;flag=y; node.resize(n<<2|3); maketree(1,n); } void pushup(int now){ if(!flag){ g->add(nd.id,ndl.id,0); g->add(nd.id,ndr.id,0); }else { g->add(ndl.id,nd.id,0); g->add(ndr.id,nd.id,0); } } void maketree(int s,int t,int now=1){ nd={s,t,++cnt}; if(s==t){ if(!flag) g->add(nd.id,s,0); else g->add(s,nd.id,0); return ; } maketree(s,nd.mid(),now<<1);maketree(nd.mid()+1,t,now<<1|1); pushup(now); } void query(int s,int t){ ff.clear(); count(s,t); } void count(int s,int t,int now=1){ if(s>nd.r||t<nd.l)return ; if(s<=nd.l&&t>=nd.r) { ff.emplace_back(nd.id); return ; } count(s,t,now<<1);count(s,t,now<<1|1); } }; int main() { IO; int n,q,s; cin>>n>>q>>s; graph g(n*10); segtree intree(n,&g,1,n); segtree outtree(n,&g,0,intree.cnt); int k,a,b;ll c,d; while(q--){ cin>>k; if(k==1){ cin>>a>>b>>c; g.add(a,b,c); }else if(k==2){ cin>>a>>b>>c>>d; outtree.query(b,c); for(auto &i:outtree.ff) g.add(a,i,d); }else{ cin>>a>>b>>c>>d; intree.query(b,c); for(auto &i:intree.ff) g.add(i,a,d); } } dijkstra ne(g,s); rep(i,1,n) cout<<(ne.dis[i]>=ne.INF?-1:ne.dis[i])<<' '; return 0; }