[线段树优化建图|dijkstra]Codeforces Round #406 (Div. 2) D. Legacy

6 篇文章 0 订阅
3 篇文章 0 订阅

总体思想是,使用线段树思想,用点和区间进行连边,只有当一个区间已经是最小值时才更新该区间内所有的点;具体思路参照这里:洛谷
代码实现:

#include<bits/stdc++.h>
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define debug(x) cout<<#x<<" is "<<x<<endl
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define DBG 0
#define lc(x) (x << 1)
#define rc(x) ((x << 1) | 1)
const int N = 1e5 + 5;
typedef long long ll;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll LLINF = (1LL<<60);
using namespace std;
const int mod = 998244353;
ll fast_pow(ll a,ll b){ll ans = 1;while(b){if(b&1)ans = (ans * a)%mod;a = (a * a)%mod;b>>=1;}return (ans%mod);}
inline ll read(){ll X=0; bool flag=1; char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}if(flag) return X;return ~(X-1);}
inline void write(ll X){if(X<0) {X=~(X-1); putchar('-');}if(X>9) write(X/10);putchar(X%10+'0');}
typedef pair<int,int> pii;
typedef vector<int> vi;
inline void fastIO(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);}
inline void time_cost(clock_t start_time,clock_t end_time){cout << "The run time is: " <<(double)(end_time - start_time) / CLOCKS_PER_SEC << "s" << endl;}
inline void init(){	
	
}
int n,q,s; 
const int D = 5e5;
ll dis[1000005];
vector<pair<int,int> > g[1000005];
int leaf[N];
void build(int x,int l,int r){
	if(l == r){
		leaf[l] = x;
		return;
	}
	int mid = (l + r) >> 1;
	g[x].pb(mp(lc(x),0)),g[x].pb(mp(rc(x),0));
	g[lc(x) + D].pb(mp(x + D,0)),g[rc(x) + D].pb(mp(x + D,0));
	build(lc(x),l,mid);
	build(rc(x),mid + 1,r);
}
void connect(int x,int curl,int curr,int u,int ql,int qr,int w,int type){
	if(ql <= curl && qr >= curr){
		if(type % 2)
			g[x + D].pb(mp(leaf[u],w));
		else
			g[leaf[u] + D].pb(mp(x,w));
		return;
	}
	int mid = (curl + curr) >> 1;
	if(qr <= mid)
		connect(lc(x),curl,mid,u,ql,qr,w,type);
	else if(ql > mid)
		connect(rc(x),mid + 1,curr,u,ql,qr,w,type);
	else
		connect(lc(x),curl,mid,u,ql,qr,w,type),connect(rc(x),mid + 1,curr,u,ql,qr,w,type);
}
inline void solve(){
	init();
	cin >> n >> q >> s;
	build(1,1,n);
	for(int i = 1;i <= n;i++)g[leaf[i]].pb(mp(leaf[i] + D,0)),g[leaf[i] + D].pb(mp(leaf[i],0));
	for(int i = 1;i <= q;i++){
		int opt,u,v,w,l,r;
		cin >> opt;
		if(opt == 1){
			cin >> u >> v >> w;
			g[leaf[u] + D].pb(mp(leaf[v],w));
		}else{
			cin >> u >> l >> r >> w;
			connect(1,1,n,u,l,r,w,opt % 2);
		}
	}
	priority_queue<pair<ll,int>,vector<pair<ll,int> >, greater<pair<ll,int> > > q;
	q.push(mp(0LL,leaf[s] + D));
	
	memset(dis,0x3f,sizeof(dis));
	dis[leaf[s] + D] = 0;
	while(!q.empty()){
		auto p = q.top();
		q.pop();
		ll tmp = p.fi,u = p.se;
		if(tmp > dis[u])continue;
		for(auto pp : g[u]){
			int v = pp.fi;
			ll w = pp.se;
			if(dis[u] + w < dis[v]){
				dis[v] = dis[u] + w;
				q.push(mp(dis[v],v));
			}
		}	
	}
	for(int i = 1;i <= n;i++){
		if(dis[leaf[i]] == INF)
			cout << "-1 ";
		else
			cout << dis[leaf[i]] <<" ";
	}
} 
int main(){
	fastIO();
#if DBG
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
#endif
	solve();
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值