一只书虫仔 @ 2020-07-11 17:09:00
听到了说是点权之和二分,但是我写出来的代码没有地方可以用上
所以求助一下大佬,在哪里加上
(并且我这个代码有几个 RE 的 qwq)
#include <bits/stdc++.h>
using namespace std;
struct node {
int val, next, length;
} e[100086];
int n, m, b, cnt;
int f[10086];
int head[50086];
int dist[50086], sum[50086];
const int inf = 0x3f3f3f3f;
void AddEdge (int u, int v, int w) {
e[++cnt].val = v;
e[cnt].next = head[u];
e[cnt].length = w;
head[u] = cnt;
}
struct cmp {
bool operator () (int a, int b) {
return dist[a] > dist[b];
}
};
priority_queue <int, vector<int>, cmp> q;
void SPFA () {
for (int i = 1; i <= n; i++)
dist[i] = inf;
int s = 1;
dist[s] = 0;
sum[s] = 1;
q.push(s);
while (!q.empty()) {
int cur = q.top();
q.pop();
sum[cur] = 0;
for (int p = head[cur]; p > 0; p = e[p].next)
if (dist[e[p].val] > dist[cur] + e[p].length) {
dist[e[p].val] = dist[cur] + e[p].length;
if (!sum[e[p].val]) {
q.push(e[p].val);
sum[e[p].val] = 1;
}
}
}
}
int main () {
scanf("%d%d%d", &n, &m, &b);
for (int i = 1; i <= n; i++)
scanf("%d", &f[i]);
for (int i = 1, u, v, w; i <= n; i++) {
scanf("%d%d%d", &u, &v, &w);
AddEdge(u, v, w);
AddEdge(v, u, w);
}
SPFA();
if (dist[n] <= b) {
printf("AFK");
return 0;
}
int low = 0, high = 1e9;
while (low <= high) {
int mid = (low + high) / 2;
if (dist[mid] <= b)
high = mid - 1;
else
low = mid + 1;
}
printf("%d", low);
return 0;
}
by 81179332_ @ 2020-07-11 21:51:58
@一只书虫仔 改好了。
#include <bits/stdc++.h>
using namespace std;
struct node {
int val, next, length;
} e[100086];
int n, m, b, cnt;
int f[10086];
int head[50086];
int dist[50086], sum[50086];
const int inf = 0x3f3f3f3f;
void AddEdge (int u, int v, int w) {
e[++cnt].val = v;
e[cnt].next = head[u];
e[cnt].length = w;
head[u] = cnt;
}
struct cmp {
bool operator () (int a, int b) {
return dist[a] > dist[b];
}
};
priority_queue <int, vector<int>, cmp> q;
int now = 1e9;
void SPFA () {
for (int i = 1; i <= n; i++)
dist[i] = inf;
int s = 1;
dist[s] = 0;
sum[s] = 1;
q.push(s);
while (!q.empty()) {
int cur = q.top();
q.pop();
sum[cur] = 0;
for (int p = head[cur]; p > 0; p = e[p].next)
if (f[e[p].val] <= now && dist[e[p].val] > dist[cur] + e[p].length) {
dist[e[p].val] = dist[cur] + e[p].length;
if (!sum[e[p].val]) {
q.push(e[p].val);
sum[e[p].val] = 1;
}
}
}
}
int main () {
scanf("%d%d%d", &n, &m, &b);
for (int i = 1; i <= n; i++)
scanf("%d", &f[i]);
for (int i = 1, u, v, w; i <= m; i++) {
scanf("%d%d%d", &u, &v, &w);
AddEdge(u, v, w);
AddEdge(v, u, w);
}
SPFA();
if (dist[n] > b) {
printf("AFK");
return 0;
}
int low = 0, high = 1e9,ans = 1e9;
while (low <= high) {
int mid = (low + high) / 2;
now = mid,SPFA();
if (dist[n] <= b)
high = mid - 1,ans = min(ans,mid);
else
low = mid + 1;
}
printf("%d", ans);
return 0;
}
把低级错误改好了再求助会更好吧,您的读入都把
我们要求的是最大的点权最小,二分这个最大的点权,则所有点权比二分的
所以我们把不能走的点去掉,每二分一个
另外 SPFA 最好还是不要写的两不像把。。
by 一只书虫仔 @ 2020-07-11 22:01:18
@81179332_ 嗯,好的,谢谢!
by 一只书虫仔 @ 2020-07-11 22:05:37
@81179332_ SPFA 大概就是我打模板的时候就按照优先队列打的,然后就改不过来了(