bzoj4400
/*
* 此题同bzoj2725
* 增加了枚举边的操作
*/
#include <bits/stdc++.h> const int N = 2e5 + ;// oo = 999999999; #define LL long long const LL oo = 9e18; int n, m, S, T;
int Short_path[N], Snum[N], Tnum[N], Id[N], path_js;
bool vis[N];
int head[N], now;
struct Node {int u, v, w, nxt;} G[N << ];
LL dis_s[N], dis_t[N];
LL Minn[N << ], Ans[N]; inline void Add(int u, int v, int w) {
G[++ now].v = v, G[now].w = w, G[now].nxt = head[u], head[u] = now;
} struct Node_ {
int u; LL dis;
bool operator < (const Node_ a) const {return dis > a.dis;}
}; std:: priority_queue <Node_> Q; void Dijkstra(int start, LL dis_[]) {
for(int i = ; i <= n; i ++) dis_[i] = oo, vis[i] = ;
Node_ now; now = (Node_) {start, }; dis_[start] = ;
Q.push(now);
while(!Q.empty()) {
Node_ topp = Q.top();
Q.pop();
if(vis[topp.u]) continue;
vis[topp.u] = ;
for(int i = head[topp.u]; ~ i; i = G[i].nxt) {
int v = G[i].v;
if(dis_[v] > dis_[topp.u] + G[i].w) {
dis_[v] = dis_[topp.u] + G[i].w;
Q.push((Node_) {v, dis_[v]});
}
}
}
} inline void Bfs(int x, LL dis_[], int bel[]) {
std:: queue <int> Q1;
Q1.push(Short_path[x]);
bel[Short_path[x]] = x;
while(!Q1.empty()) {
int topp = Q1.front();
Q1.pop();
for(int i = head[topp]; ~ i; i = G[i].nxt) {
int v = G[i].v;
if(!Id[v] && !bel[v] && dis_[v] == dis_[topp] + G[i].w) {
bel[v] = x;
Q1.push(v);
}
}
}
} #define lson jd << 1
#define rson jd << 1 | 1 void Sec_G(int l ,int r, int jd, int x, int y, LL num) {
if(x <= l && r <= y) {
Minn[jd] = std:: min(Minn[jd], (LL)num);
return ;
}
int mid = (l + r) >> ;
if(x <= mid) Sec_G(l, mid, lson, x, y, num);
if(y > mid) Sec_G(mid + , r, rson, x, y, num);
} void Dfs_tree(int l, int r, int jd) {
if(l == r) {
Ans[l] = Minn[jd];
return ;
}
int mid = (l + r) >> ;
Minn[lson] = std:: min(Minn[lson], Minn[jd]);
Minn[rson] = std:: min(Minn[rson], Minn[jd]);
Dfs_tree(l, mid, lson), Dfs_tree(mid + , r, rson);
} #define gc getchar() inline LL read() {
LL x = ; char c = gc;
while(c < '' || c > '') c = gc;
while(c >= '' && c <= '') x = x * + c - '', c = gc;
return x;
} bool visit[N << ]; int main() {
n = read(), m = read();
for(int i = ; i <= (N << ); i ++) Minn[i] = oo;
for(int i = ; i <= n; i ++) head[i] = -;
for(int i = ; i <= m; i ++) {
int u = read(), v = read(), w = read();
Add(u, v, w), Add(v, u, w);
}
S = , T = n;
Dijkstra(S, dis_s);
Dijkstra(T, dis_t);
for(int i = S; i != T; i = i) {
// visit[i] = 1;
Short_path[++ path_js] = i;
Id[i] = path_js;
for(int j = head[i]; ~ j; j = G[j].nxt) {
if(dis_t[i] == G[j].w + dis_t[G[j].v]) {
i = G[j].v;
visit[j] = ;
break;
}
}
}
Short_path[path_js + ] = T, Id[T] = path_js + ;
for(int i = ; i <= path_js; i ++) Bfs(i, dis_s, Snum);
for(int i = path_js + ; i >= ; i --) Bfs(i, dis_t, Tnum);
for(int i = ; i <= n; i ++) {
for(int j = head[i]; ~ j; j = G[j].nxt) {
int v = G[j].v;
if(visit[j]) continue;
if(Snum[i] < Tnum[v] && Snum[i] && Tnum[v]) {
Sec_G(, path_js, , Snum[i], Tnum[v] - , dis_s[i] + G[j].w + dis_t[v]);
}
}
}
Dfs_tree(, path_js, );
LL Dis = , js;
for(int i = ; i <= path_js; i ++) {
if(Ans[i] > Dis && Ans[i] != oo) Dis = Ans[i], js = ;
else if(Ans[i] == Dis) js ++;
}
if(Dis == dis_s[T]) js += m - path_js;
std:: cout << Dis << " " << js;
return ;
}
?
bzoj4400的更多相关文章
- bzoj4400: tjoi2012 桥
先传代码再填坑 #include <iostream> #include <cstdio> #include <cmath> #include <cstrin ...
- BZOJ4400 TJOI2012桥(最短路+线段树)
首先找出任意一条1-n的最短路径.显然删除的边只有在该最短路上才会对最短路长度产生影响. 不会证明地给出一个找不到反例的结论:删除一条边后,新图中一定有一条1-n的最短路径上存在一条边x->y, ...
随机推荐
- 『Django』第N+1节: Django自带的认证系统 - auth
个人网站: lipeiguan.top 以后会慢慢转移到个人网站, 欢迎大家收藏^ . ^ 写在前面 我们在开发一个网站的时候, 经常需要实现网站的用户系统. 这个时候我们需要实现用户注册.用户登录. ...
- scratch少儿编程——03、动作:运动的开始,游戏的基础。
各位小伙伴大家好: 从这一期开始我们来学Scratch的具体操作. 第一季我们会从每一个脚本模块开始.一个程序块一个程序块去操作,感受它的效果. 今天我们来一起学习程序区的脚本类动作模块的指令. 动作 ...
- 把QString写到文件中可以用toutf8()函数
把QString写到文件中可以用toutf8()函数 QByteArray QString::toUtf8() const Returns a UTF-8 representation of the ...
- asp.net MVC 抓取微信文章数据(正文)
1.抓微信的正文主要是调用第三方的接口(https://market.aliyun.com/products/56928004/cmapi012134.html) using Newtonsoft.J ...
- js 监听键盘的enter键
// js 版本 window.onload=function(){ document.onkeydown=function(ev){ var event=ev ||event if(event.ke ...
- Mysql分表和分区的区别、分库和分表区别
一,什么是mysql分表,分区 什么是分表,从表面意思上看呢,就是把一张表分成N多个小表,具体请看:mysql分表的3种方法. 什么是分区,分区呢就是把一张表的数据分成N多个区块,这些区块可以在同一个 ...
- android 蓝牙连接端(客户端)封装
0.权限 AndroidManifest.xml <uses-permission android:name="android.permission.BLUETOOTH"/ ...
- iis 虚拟目录 文件服务器
需求 多节点站点部署时,上传文件地址统一 调整步骤如下 建立文件服务器 共享目录 设置账号密码 各服务器建账号 密码 需与文件服务器账号密码一致 调整 web.config 在<system.w ...
- 分析js跳出循环的几种方法
Break语句: break语句会使运行的程序立刻退出包含在最内层的循环或者退出一个switch语句. 由于它是用来退出循环或者switch语句的, 所以只有当它出现在这些语句的时候, 这种形式的br ...
- mongodb备份每一天的数据
需求:把mongodb里面存储6个月的数据备份到本地,一天天的来备份,方便对备份管理.然后mongo保留一周的数据(优化查询速度,可以用mongo的ttl来实现,但是我的业务场景不太适合用ttl索引) ...