链接:https://www.nowcoder.com/acm/contest/79/E
来源:牛客网
题目描述
小欧在上代数课的时候,老师向大家提出了一个问题,不定方程 ax+by=c 的整数解存在的充要条件是什么。
聪明的小欧立即举手给出了老师一个完美的回答,放学后,老师叫住小欧给了他一个思考题。
给出正整数 a 和 b 的值以及两个序列 S 和 V, 求出最小代价的正整数 c 使得不定方程 ax+by=c 有解,且 c 必须满足以下条件:
1. 组成 c 的数字必须是序列 S 内的。
2. 每使用序列 S 内的一个数字 Si 就会消耗掉代价 Vi。
3. 序列 S 内的数字使用次数不限。
4. c 的首位为 u, c的末位为 v。(u,v 也是序列 S 内的)
如果有多个代价一样小的答案,只需要 c 的字典序最小的那一个。
聪明的小欧立即举手给出了老师一个完美的回答,放学后,老师叫住小欧给了他一个思考题。
给出正整数 a 和 b 的值以及两个序列 S 和 V, 求出最小代价的正整数 c 使得不定方程 ax+by=c 有解,且 c 必须满足以下条件:
1. 组成 c 的数字必须是序列 S 内的。
2. 每使用序列 S 内的一个数字 Si 就会消耗掉代价 Vi。
3. 序列 S 内的数字使用次数不限。
4. c 的首位为 u, c的末位为 v。(u,v 也是序列 S 内的)
如果有多个代价一样小的答案,只需要 c 的字典序最小的那一个。
输入描述:
第一行三个个整数 a,b,n (1 <= a, b <= 100000, 2 <= n <= 10)i
第二行 n 个整数 S
(0 <= Si
<= 9)i
第三行 n 个整数 V
(1 <= Vi
<= 1000)
最后一行两个整数 u,v(1 <= u <= 9, 0 <= v <= 9, u != v)
输出描述:
输出一行表示满足条件的 c 。
如果有多个输出字典序最小的。
如果不存在输出 -1 。
示例1
输入
10 15 2 2 0 1 1 2 0
输出
20
示例2
输入
17 17 4 0 1 2 7 1 1 1 1000 1 0
输出
1020
思路:对于0到1e5的每一个值建一个节点,每个数字对应一条边,u到v有一条数字为x的边当且仅当(u * 10 + x) % gcd(a, b) == v。想到这里,建图完毕直接跑个dij就行了。但是有一个问题,要输出字典序最小路径,正向可能不好记录,
可以反向建图跑最短路。反向图的起点值是0,连接所有 满足(w * 10 + v) % 10 == 0的w节点即可,但这个0与路径上普通的节点0是不同的,我们要将这个点特殊化一下,可以赋成一个独特的下标10001。最后求10001到u的最短路即可,更新路径
时根据决策记录上一个节点以及到达此节点的边。

1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pli pair<ll, int> 27 #define pii pair<int, int> 28 #define pb push_back 29 #define mp make_pair 30 #define clr(a, x) memset(a, x, sizeof(a)) 31 32 const double pi = acos(-1.0); 33 const int INF = 0x3f3f3f3f; 34 const int MOD = 1e9 + 7; 35 const double EPS = 1e-9; 36 37 /* 38 #include <ext/pb_ds/assoc_container.hpp> 39 #include <ext/pb_ds/tree_policy.hpp> 40 41 using namespace __gnu_pbds; 42 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 43 */ 44 45 int a, b, n, s[15], val[15], u, v, g, cost[15]; 46 int dis[100015]; 47 pii pre[100015]; 48 struct edge { 49 int v, x; 50 edge () {} 51 edge (int v, int x) : v(v), x(x) {} 52 }; 53 vector<edge> E[100015]; 54 55 int gcd(int a, int b) { 56 return b ? gcd(b, a % b) : a; 57 } 58 59 void build_graph() { 60 for (int i = 0; i <= 100000; ++i) { 61 for (int j = 0; j < 10; ++j) { 62 if (INF != cost[j]) { 63 //E[i].pb(mp((i * 10 + j) % g, cost[j])); 64 if ((i * 10 + j) % g == i) continue; 65 E[(i * 10 + j) % g].pb(edge(i, j)); 66 } 67 } 68 } 69 for (int i = 0; i <= 100000; ++i) { 70 if (0 == (i * 10 + v) % g) { 71 E[100001].pb(edge(i, v)); 72 } 73 } 74 } 75 76 int dij() { 77 clr(dis, INF); 78 for (int i = 0; i < 100010; ++i) { 79 pre[i].first = INF; 80 pre[i].second = INF; 81 } 82 priority_queue<pli, vector<pli>, greater<pli> > que; 83 int s = 100001; 84 que.push(pli(dis[s] = 0, s)); 85 while (que.size()) { 86 pli p = que.top(); que.pop(); 87 ll d = p.first; 88 int x = p.second; 89 if (dis[x] < d) continue; 90 for (int i = 0; i < E[x].size(); ++i) { 91 int y = E[x][i].v, v = E[x][i].x; 92 /*if (x == y) { 93 printf("x = y = %d ", x); 94 pau; 95 }*/ 96 int td = d + cost[v]; 97 if (dis[y] < td) continue; 98 if (td < dis[y]) { 99 que.push(pli(dis[y] = td, y)); 100 pre[y] = mp(x, v); 101 } else { 102 if (v < pre[y].second) pre[y] = mp(x, v); 103 } 104 } 105 } 106 return dis[u]; 107 } 108 109 int main() { 110 scanf("%d%d%d", &a, &b, &n); 111 g = gcd(a, b); 112 clr(cost, INF); 113 for (int i = 1; i <= n; ++i) { 114 scanf("%d", &s[i]); 115 } 116 for (int i = 1; i <= n; ++i) { 117 scanf("%d", &val[i]); 118 cost[s[i]] = min(cost[s[i]], val[i]); 119 } 120 scanf("%d%d", &u, &v); 121 build_graph(); 122 if (INF == dij()) { 123 puts("-1"); 124 } else { 125 printf("%d", u); 126 int s = u; 127 while (100001 != s) { 128 printf("%d", pre[s].second); 129 s = pre[s].first; 130 } 131 } 132 return 0; 133 }