Atcoder 084D

分析:这题脑洞新奇...居然是最短路...将0到k-1看做k个点,第t个点向(10*t+0,1,2...,9)%k连一条长度为0,,1,2,..,9的边,然后枚举s=1,2,...,9,算出所有从s到0的最短路,答案就是最短路+s的最小值。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 #include<queue>
 6 using namespace std;
 7 const int maxn = 1e5 + 5, inf = 1e9;
 8 struct Edge{
 9     int to,dis;
10     Edge(int _to, int _dis):to(_to), dis(_dis){}
11 };
12 vector<Edge> G[maxn];
13 bool inq[maxn];
14 int dis[maxn];
15 int n;
16 queue<int> Q;
17 int spfa(int s){
18     for(int i = 0; i < n; i++)dis[i] = inf;
19     memset(inq, 0, sizeof(inq));
20     Q.push(s);
21     dis[s] = 0;
22     inq[s] = true;
23     while(!Q.empty()){
24         int u = Q.front();Q.pop();
25         inq[u] = false;
26         for(int i = 0; i < G[u].size(); i++){
27             Edge &e = G[u][i];
28             if(dis[e.to] > dis[u] + e.dis){
29                 dis[e.to] = dis[u] + e.dis;
30                 if(!inq[e.to])inq[e.to] = true, Q.push(e.to);
31             }
32         }
33     }
34     return s + dis[0];
35 }
36 void build(){
37     for(int i = 1; i < n; i++){
38         for(int j = 0; j <= 9; j++){
39             G[i].push_back(Edge((10 * i + j) % n, j));
40         }
41     }
42 }
43 int main(){
44     cin>>n;
45     build();
46     int ans = inf;
47     for(int s = 1; s <= 9; s++)ans = min(ans, spfa(s));
48     cout<<ans<<endl;
49     return 0;
50 }
原文地址:https://www.cnblogs.com/7391-KID/p/7816198.html