题目
spfa代码
#include <bits/stdc++.h>
using namespace std;
const int N = 2050, M = 2e5+N;
int h[N], e[M], ne[M], w[M], p[M], idx;
int tt[N];
int dist[N];
bool st[N];
int n, m, k, u;
void add(int a, int b, int c)
{
e[idx] = c, w[idx] = max(tt[a], tt[b]), p[idx] = b;
ne[idx] = h[a], h[a] = idx++;
}
void spfa(int s)
{
memset(dist, 0x3f, sizeof dist);
queue<int> q;
q.push(s);
st[s] = true;
dist[s] = 0;
while(q.size())
{
int t = q.front(); q.pop(); st[t] = false;
for(int i = h[t]; ~i; i = ne[i])
{
int j = e[i];
if(dist[j] > max(dist[t], dist[p[i]]) + w[i])
{
dist[j] = max(dist[t], dist[p[i]]) + w[i];
if(!st[j])
{
q.push(j);
st[j] = true;
}
}
}
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> k >> u;
for(int i = 1; i <= n; i++) cin >> tt[i];
memset(h, -1, sizeof h);
int s = 0;
for(int i = 1; i <= m; i++)
{
int x;
cin >> x;
add(s, 0, x);
}
for(int i = 1; i <= k; i++)
{
int a, b, c;
cin >> a >> b >> c;
add(a, b, c);
add(b, a, c);
}
spfa(s);
cout << dist[u];
return 0;
}
Dijkstra代码
#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int, int> PII;
const int N = 2050, M = 2e5+N;
int h[N], e[M], ne[M], w[M], p[M], idx;
int tt[N];
int dist[N];
bool st[N];
int n, m, k, u;
void add(int a, int b, int c)
{
e[idx] = c, w[idx] = max(tt[a], tt[b]), p[idx] = b;
ne[idx] = h[a], h[a] = idx++;
}
void dijkstra(int s)
{
memset(dist, 0x3f, sizeof dist);
priority_queue<PII, vector<PII>, greater<PII>> heap;
heap.push({0, s});
dist[s] = 0;
while(heap.size())
{
auto t = heap.top(); heap.pop();
int ty = t.y, tx = t.x;
if(st[ty]) continue;
else st[ty] = false;
for(int i = h[ty]; ~i; i = ne[i])
{
int j = e[i];
if(dist[j] > max(tx, dist[p[i]]) + w[i])
{
dist[j] = max(tx, dist[p[i]]) + w[i];
heap.push({dist[j], j});
}
}
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> k >> u;
for(int i = 1; i <= n; i++) cin >> tt[i];
memset(h, -1, sizeof h);
int s = 0;
for(int i = 1; i <= m; i++)
{
int x;
cin >> x;
add(s, 0, x);
} //N
for(int i = 1; i <= k; i++)
{
int a, b, c;
cin >> a >> b >> c;
add(a, b, c);
add(b, a, c);
} //2K
dijkstra(s);
cout << dist[u];
return 0;
}
感想
额,就是没想到这样转移距离。这种构图还是不难想的。我觉得得从题意和可行性两个方面来思考。题意要AB杂交得到C,那么dist[A] 和 dist[B]两个达到的代价取最大值即可(想一想),手里有多个种子,用一个超级源点把他们聚合接起来。从可行性上讲,可行。
还是老规矩,add函数的使用次数要标出来,防止因为开太小导致错误。