0
点赞
收藏
分享

微信扫一扫

The 2021 CCPC Guilin Tax(爆搜)

phpworkerman 2022-04-16 阅读 31
算法

The 2021 CCPC Guilin Tax(爆搜)

链接
题意:给出每个边管理的人,第几次通过这个人管理的边需要支付的代价是 k ∗ w i k*w_i kwi,从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;
}

举报

相关推荐

0 条评论