CodeForces - 786B -- 线段树优化建图
2024-09-06 17:13:06
刚开始想了两个小时,打算把区间分块然后计算,但是这就很灵性了看了一个大佬的博客,侵删
#include<cstring>
#include<iostream>
#include<vector>
#include<cstdio>
#include<queue>
#define maxn 302020 using namespace std;
typedef long long ll;
const ll INF = 10000000000000;
int root1 = 0;
int root2 = 0;
struct Node {
int p;
ll len;
Node(int a, ll b) :p(a), len(b) {}
};
vector<Node>G[maxn];
void insert(int be, int en, ll len) {
G[be].push_back(Node(en, len));
} ll dis[maxn];
int vis[maxn];
int num;
int lc[maxn];
int rc[maxn]; int bult1(int &node, int be, int en) {
if (be == en) {
node = be;
return 0;
}
node = ++num;
int mid = (be + en) / 2;
bult1(lc[node], be, mid);
bult1(rc[node], mid + 1, en);
insert(node, lc[node], 0);
insert(node, rc[node], 0);
return 0;
} int bult2(int &node, int be, int en) {
if (be == en) {
node = be;
return 0;
}
node = ++num;
int mid = (be + en) / 2;
bult2(lc[node], be, mid);
bult2(rc[node], mid + 1, en); insert(lc[node], node, 0);
insert(rc[node], node, 0);
return 0;
}
int n, m, s;
ll length;
int LL, RR;
int querry(int node, int be, int en, int op,int begin) {
if (LL <= be && en <= RR) { if (op == 2) insert(begin, node, length);
if (op == 3) insert(node, begin, length);
return 0;
}
int mid = (be + en) / 2;
if (LL <= mid) querry(lc[node], be, mid, op, begin);
if (mid < RR) querry(rc[node], mid + 1, en, op, begin);
return 0;
}
int dijstra(int be) {
for (int i = 0; i < maxn -100; i++) {
vis[i] = 0;
dis[i] = INF;
}
queue<int>que;
que.push(be);
dis[be] = 0;
while (!que.empty()) {
int x = que.front();
que.pop();
vis[x] = 0;
for (int i = 0; i < G[x].size(); i++) {
int p = G[x][i].p;
if (dis[p] > dis[x] + G[x][i].len) {
dis[p] = dis[x] + G[x][i].len;
if (!vis[p]) {
vis[p] = 1;
que.push(p);
} }
}
}
return 0;
}
int main() {
int t;
scanf("%d %d %d", &n, &m, &s);
num = n+1;
bult1(root1, 1, n);
bult2(root2, 1, n);
int be, en; for (int i = 0; i < m; i++) {
scanf("%d", &t);
if (t == 1) {
scanf("%d %d %lld", &be, &en, &length);
insert(be, en, length);
}
else {
scanf("%d %d %d %lld", &be, &LL, &RR,&length);
if (t == 2) querry(root1, 1, n, t, be);
else querry(root2, 1, n, t, be);
}
}
dijstra(s);
for (int i = 1; i <= n; i++) {
if (dis[i] == INF) printf("-1 ");
else printf("%lld ", dis[i]);
}
return 0;
}
最新文章
- CSS中的overflow属性
- Oracle 行转列,列转行
- 项目回顾3-再谈图片上传-FormData+ajax上传
- PowerDesigner连接MySQL,建立逆向工程图解
- ASP.NET中application对象的用法
- JAVA常用关键字
- Svn 的 Update 与Maven 的update project 作用有什么区别
- ActionBar 的简单使用
- Masonry 控件详解
- Nginx+Keepalived主备切换(包含nginx服务停止)
- windows 环境怎样恢复 (oracle 11g grid) ocr voting 损坏的集群
- Java基础知识二次学习--第五章 数组
- JS5模拟类
- C#调用java方法踩坑记
- CentOS 7 安装与卸载MySQL 5.7
- ES6 块级作用域
- elasticsearch简单操作(二)
- Azure系列2.1.11 —— CloudBlobContainer
- pycharm import pygame 出现报错:No module named &#39;pygame&#39;
- springmvc sessionfilter 登录过滤器