AT3621 [ARC084B] Small Multiple

https://www.luogu.com.cn/problem/AT3621

考虑x可以怎么变换
可以变成 10 x , 10 x + j 10x,10x+j 10x,10x+j费用就是 j j j
那么只需要跑个最短路就行了
code:

#include<bits/stdc++.h>
#define N 400050
using namespace std;
struct edge {
    int v, nxt, c;
} e[N * 10 << 1];
int p[N], eid;
void init() {
    memset(p, -1, sizeof p);
    eid = 0;
}
void insert(int u, int v, int c) {
    e[eid].v = v;
    e[eid].c = c;
    e[eid].nxt = p[u];
    p[u] = eid ++;
}
priority_queue<pair<int, int> > q;
int dis[N], n, vis[N];
void dij() {
    memset(dis, 0x3f, sizeof dis);
    for(int i = 1; i <= 9; i ++) dis[i] = i, q.push(make_pair(-i, i));
    while(q.size()) {
        int u = q.top().second; q.pop();
        if(vis[u]) continue;
        vis[u] = 1;
        for(int i = p[u]; i + 1; i = e[i].nxt) {
            int v = e[i].v;
            if(vis[v]) continue;
            if(dis[v] > dis[u] + e[i].c) {
                dis[v] = dis[u] + e[i].c;
                q.push(make_pair(-dis[v], v));
            }
        }
    }
}
int main() {
    init();
    scanf("%d", &n);
    for(int i = 1; i < n; i ++) {
        insert(i, i * 10 % n, 0);
        for(int j = 1; j <= 9; j ++) {
            insert(i, (i * 10 + j) % n, j);
        }
    }
    dij();
    printf("%d", dis[0]);
    return 0;
}
posted @ 2021-10-26 15:06  lahlah  阅读(55)  评论(0编辑  收藏  举报