2 条题解
-
0
题目求 d[ i ]最小值,所以跑最长路。d[ a ] + x <= d[ b ],从 a 到 b 边权为 x 的边;d[ 0 ]+si <= d[ i ],从 0 到 i 边权为 si 的边;以0为起点跑一遍最长路(若数据有可能没有提到0,则所有点都得进入队列,但只有d[0]=0)。
#include <bits/stdc++.h> using namespace std; const int N=1e5+10; vector<pair<int, int>> G[N]; int d[N]; bool v[N]; void spfa() { queue<int> q; memset(d, -0x3f, sizeof(d)); memset(v,0,sizeof(v)); q.push(0);d[0]=0;v[0]=1; while(!q.empty()) { int x=q.front();q.pop(); v[x]=0; for(auto i:G[x]) { int y=i.first, c=i.second; if(d[y]<d[x]+c) { d[y]=d[x]+c; if(!v[y]) q.push(y),v[y]=1; } } } } int main() { int n, m, c;scanf("%d%d%d", &n, &m, &c); for(int i=1, si;i<=n;i++) { scanf("%d", &si); G[0].push_back({i, si}); //d[0]+si<=d[i] } for(int i=1;i<=c;i++) { int a, b, x;scanf("%d%d%d", &a, &b, &x); G[a].push_back({b, x}); //d[a]+x <= d[ b ] } spfa(); for(int i=1;i<=n;i++)printf("%d\n", d[i]); return 0; } -
0
/* 题目求 d[ i ]最小值,所以跑最长路 d[ a ] + x <= d[ b ] ,从 a 到 b 边权为 x 的边; d[ 0 ]+Si <= d[ i ],从 0 到 i 边权为 Si 的边; 以0为起点跑一遍最长路(若数据有可能没有提到0,则所有点都得进入队列,但只有d[0]=0)。 */ #include<bits/stdc++.h> using namespace std; const int N=1e5+10; vector<pair<int, int>> G[N]; int d[N]; bool v[N]; void spfa() { queue<int> q; memset(d, -0x3f, sizeof(d)); memset(v,0,sizeof(v)); q.push(0);d[0]=0;v[0]=1; while(!q.empty()) { int x=q.front();q.pop(); v[x]=0; for(auto i:G[x]) { int y=i.first, c=i.second; if(d[y]<d[x]+c) { d[y]=d[x]+c; if(!v[y]) q.push(y),v[y]=1; } } } } int main() { int n,m,c;scanf("%d%d%d",&n,&m,&c); for(int i=1,si;i<=n;i++) { scanf("%d", &si); G[0].push_back({i,si}); //d[0]+si<=d[i] } for(int i=1;i<=c;i++) { int a,b,x;scanf("%d%d%d",&a,&b,&x); G[a].push_back({b, x}); //d[a]+x <= d[ b ] } spfa(); for(int i=1;i<=n;i++)printf("%d\n", d[i]); return 0; }
- 1
信息
- ID
- 6882
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- 递交数
- 173
- 已通过
- 21
- 上传者