JZOJ 5818. 【NOIP提高A组模拟2018.8.15】 做运动
Y 君将学校中的所有地点编号为 1 到 n,其中她的教学楼被编号为 S,她的食堂被编号为 T
学校中有 m 条连接两个点的双向道路,保证从任意一个点可以通过道路到达学校中的所有点。
然而 Y 君不得不面临一个严峻的问题,就是天气十分炎热,如果 Y 君太热了,她就会中暑。
于是 Y 君调查了学校中每条路的温度 t,及通过一条路所需的时间 c。
Y 君在温度为 t 的地 方跑单位时间,就会使她的热量增加 t。
由于热量过高 Y 君就会中暑,而且 Y 君也希望在温度较低的路上跑,她希望在经过的所有道路中最高温度最低的前提下,使她到达食堂时的热量最低
从教学楼出发时,Y 君的热量为 0。
请你帮助 Y 君设计从教学楼到食堂的路线,以满足她的要求。
你只需输出你设计的路线中所 有道路的最高温度和 Y 君到达食堂时的热量。
10% 的数据满足 t = 0
另外 10% 的数据满足 c = 0
另外 30% 的数据满足 n ≤ 2000
100% 的数据满足 n ≤ 5 × 10^5 , m ≤ 10^6 , 0 ≤ t ≤ 10000, 0 ≤ c ≤ 10^8 , 1 ≤ a, b, S, T ≤ n, S ≠ T
一开始想出了个$O(n \log^2 n)$的二分+dij的没什么用的算法……
实际上不需要这么复杂,把边的t值从小到大排序后依次加边,当S和T第一次连通时跑dij就行了……
注意相同t值的边需要一起加入……

1 %:pragma GCC optimize(2) 2 %:pragma GCC optimize(3) 3 %:pragma GCC optimize("Ofast") 4 %:pragma GCC optimize("inline") 5 %:pragma GCC optimize("-fgcse") 6 %:pragma GCC optimize("-fgcse-lm") 7 %:pragma GCC optimize("-fipa-sra") 8 %:pragma GCC optimize("-ftree-pre") 9 %:pragma GCC optimize("-ftree-vrp") 10 %:pragma GCC optimize("-fpeephole2") 11 %:pragma GCC optimize("-ffast-math") 12 %:pragma GCC optimize("-fsched-spec") 13 %:pragma GCC optimize("unroll-loops") 14 %:pragma GCC optimize("-falign-jumps") 15 %:pragma GCC optimize("-falign-loops") 16 %:pragma GCC optimize("-falign-labels") 17 %:pragma GCC optimize("-fdevirtualize") 18 %:pragma GCC optimize("-fcaller-saves") 19 %:pragma GCC optimize("-fcrossjumping") 20 %:pragma GCC optimize("-fthread-jumps") 21 %:pragma GCC optimize("-funroll-loops") 22 %:pragma GCC optimize("-fwhole-program") 23 %:pragma GCC optimize("-freorder-blocks") 24 %:pragma GCC optimize("-fschedule-insns") 25 %:pragma GCC optimize("inline-functions") 26 %:pragma GCC optimize("-ftree-tail-merge") 27 %:pragma GCC optimize("-fschedule-insns2") 28 %:pragma GCC optimize("-fstrict-aliasing") 29 %:pragma GCC optimize("-fstrict-overflow") 30 %:pragma GCC optimize("-falign-functions") 31 %:pragma GCC optimize("-fcse-skip-blocks") 32 %:pragma GCC optimize("-fcse-follow-jumps") 33 %:pragma GCC optimize("-fsched-interblock") 34 %:pragma GCC optimize("-fpartial-inlining") 35 %:pragma GCC optimize("no-stack-protector") 36 %:pragma GCC optimize("-freorder-functions") 37 %:pragma GCC optimize("-findirect-inlining") 38 %:pragma GCC optimize("-fhoist-adjacent-loads") 39 %:pragma GCC optimize("-frerun-cse-after-loop") 40 %:pragma GCC optimize("inline-small-functions") 41 %:pragma GCC optimize("-finline-small-functions") 42 %:pragma GCC optimize("-ftree-switch-conversion") 43 %:pragma GCC optimize("-foptimize-sibling-calls") 44 %:pragma GCC optimize("-fexpensive-optimizations") 45 %:pragma GCC optimize("-funsafe-loop-optimizations") 46 %:pragma GCC optimize("inline-functions-called-once") 47 %:pragma GCC optimize("-fdelete-null-pointer-checks") 48 49 #include <bits/stdc++.h> 50 using namespace std; 51 const int N = 1e6 + 10; 52 typedef long long ll; 53 struct TT { int to; ll w; }; 54 bool operator < (TT a, TT b) { return a.w > b.w; } 55 vector<TT> g[N]; 56 struct E { int u, v, t, c; } e[N]; 57 bool operator < (E a, E b) { return a.t < b.t; } 58 int S, T; 59 ll dis[N]; 60 int vis[N], n, m; 61 int fa[N]; 62 ll dij() { 63 priority_queue<TT> pq; 64 for(int i = 1 ; i <= n ; ++ i) dis[i] = 1ll << 60, vis[i] = 0; 65 pq.push((TT) { S, dis[S] = 0 }); 66 while(pq.size()) { 67 int u = pq.top().to; pq.pop(); 68 if(vis[u]) continue; vis[u] = 1; 69 for(auto e: g[u]) 70 if(dis[e.to] > dis[u] + e.w) 71 pq.push((TT) { e.to, dis[e.to] = dis[u] + e.w }); 72 } 73 return dis[T]; 74 } 75 int get(int x) { return fa[x] == x ? fa[x] : fa[x] = get(fa[x]); } 76 int main() { 77 freopen("running.in", "r", stdin); 78 freopen("running.out", "w", stdout); 79 scanf("%d%d", &n, &m); 80 for(int i = 1 ; i <= m ; ++ i) scanf("%d%d%d%d", &e[i].u, &e[i].v, &e[i].t, &e[i].c); 81 scanf("%d%d", &S, &T); 82 sort(e + 1, e + 1 + m); 83 iota(fa + 1, fa + 1 + n, 1); 84 for(int i = 1 ; i <= m ; ++ i) { 85 int u = e[i].u, v = e[i].v, t = e[i].t, c = e[i].c; 86 fa[get(u)] = get(v); 87 g[u].push_back((TT) { v, 1ll * t * c }); 88 g[v].push_back((TT) { u, 1ll * t * c }); 89 if(get(S) == get(T) && (i == m || t != e[i + 1].t)) { 90 printf("%d %lld\n", t, dij()); 91 break; 92 } 93 } 94 }