思路
AC(SPFA + two point)
#include <bits/stdc++.h>
using namespace std;
const LL INF = 0x3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const int N = 1e5 + 10;
int h[N], e[N], ne[N], idx;
LL tmp[N], dist[N], w[N];
bool leaf[N];
void add(int a, int b, int c) {
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}
void spfa() {
memset(dist, 0x3f, sizeof dist);
queue<int> Q;
Q.push(1);
dist[1] = 0;
while (Q.size()) {
int t = Q.front();
Q.pop();
LL mi = INF;
for (int i = h[t]; i != -1; i = ne[i]) {
if (w[i] < mi)
mi = w[i];
Q.push(e[i]);
}
for (int i = h[t]; i != -1; i = ne[i]) {
int j = e[i];
dist[j] = min(dist[j], dist[t] + mi + 2 *(w[i] - mi));
}
}
}
bool check(int mid, LL p) {
if (tmp[mid] > p) return 1;
else return 0;
}
int main() {
int t;
scanf("%d", &t);
while (t -- ) {
int n;
idx = 0;
memset(leaf, 0, sizeof leaf);
memset(h, -1, sizeof h);
scanf("%d", &n);
for (int i = 1; i < n; i ++ ) {
int p, c;
scanf("%d%d", &p, &c);
add(p, i + 1, c);
leaf[p] = 1;
}
int cnt = 0;
spfa();
for (int i = 1; i <= n; i ++ ) {
if (leaf[i] == 0)
tmp[++ cnt] = dist[i];
}
int q;
sort(tmp + 1, tmp + cnt + 1);
scanf("%d", &q);
while (q -- ) {
LL p;
scanf("%lld", &p);
int l = 0, r = cnt;
while (l < r) {
int mid = l + r + 1 >> 1;
if (check(mid, p)) r = mid - 1;
else l = mid;
}
printf("%d\n", l);
}
}
return 0;
}
思路
AC(SPFA + two point)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int e[N], ne[N], h[N], wis[N], cost[N], dist[N];
int idx, n, m, k;
bool st[N];
void add(int s1, int s2, int c, int w) {
cost[idx] = c, wis[idx] = w;
e[idx] = s2, ne[idx] = h[s1], h[s1] = idx ++;
}
bool check(int midwis){
memset(dist, 0x3f, sizeof dist);
memset(st, 0, sizeof st);
dist[1] = 0;
queue<int> q;
q.push(1);
st[1] = 1;
while (q.size()) {
int t = q.front();
q.pop();
st[t] = 0;
for (int i = h[t]; i != -1; i = ne[i]) {
int j = e[i];
if (dist[j] > dist[t] + cost[i] && dist[t] + cost[i] < k && wis[i] <= midwis) {
dist[j] = dist[t] + cost[i];
if (j == n) return 1;
if (!st[j]) {
q.push(j);
st[j] = 1;
}
}
}
}
return 0;
}
int main() {
int t;
scanf("%d", &t);
while (t -- ) {
memset(h, -1, sizeof h);
idx = 0;
scanf("%d%d%d", &n, &m, &k);
for (int i = 1; i <= m; i ++ ) {
int s1, s2, c, w;
scanf("%d%d%d%d", &s1, &s2, &c, &w);
add(s1, s2, c, w);
add(s2, s1, c, w);
}
int l = 1, r = 1e9, ans = -1;
while (l < r) {
int mid = (l + r) / 2;
if (check(mid)) {
r = mid;
ans = mid;
}
else l = mid + 1;
}
printf("%d\n", ans);
}
return 0;
}