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;
}