The 2021 CCPC Guilin Tax(爆搜)
链接
题意:给出每个边管理的人,第几次通过这个人管理的边需要支付的代价是
k
∗
w
i
k*w_i
k∗wi,从1号点出发,只会走最短路,问到其他点需要支付的代价最小多少
思路:直接爆搜莽过去了eee,正赛估计不敢写
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5+10;
int mp[66][66];
int head[N], idx;
struct Edge{int to, nxt, c;}e[N];
void add(int u, int v, int c) {e[++idx].to = v, e[idx].nxt = head[u], e[idx].c = c, head[u] = idx;}
int vis[55], dis[55], cnt[N], w[N], ans[55], n, m;
void bfs()
{
queue<int> Q;
memset(dis, 0x3f, sizeof (dis));
Q.push(1);
dis[1] = 0;
while (!Q.empty()) {
int u = Q.front(); Q.pop();
if (vis[u]) continue;
vis[u] = 1;
for (int i = 1; i <= n; i++) {
if (!mp[u][i]) continue;
int v = i;
if (dis[v] > dis[u] + 1) {
dis[v] = dis[u] + 1;
Q.push(v);
}
}
}
}
void dfs(int u, int cost)
{
ans[u] = min(ans[u], cost);
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to, c = e[i].c;
if (dis[v] - dis[u] != 1) continue;
cnt[c]++;
dfs(v, cost + w[c] * cnt[c]);
cnt[c]--;
}
}
signed main()
{
cin >> n >> m;
memset(ans, 0x3f, sizeof (ans));
for (int i = 1; i <= m; i++) {
cin >> w[i];
}
for (int i = 1; i <= m; i++) {
int u, v, c;
cin >> u >> v >> c;
mp[u][v] = mp[v][u] = c;
}
bfs();
for (int i = 1; i <= n; i++) {
for (int j = 1 + i; j <= n; j++) {
if (abs(dis[i] - dis[j]) == 1 && mp[i][j]) {add(i, j, mp[i][j]); add(j, i, mp[i][j]);}
}
}
dfs(1, 0);
for (int i = 2; i <= n; i++) cout << ans[i] << endl ;
return 0;
}