在一个棋盘上有许多格子,每个格子上都有 a1 个红宝石,a2 个绿宝石,a3 个黄宝石 … an 个紫宝石,保证对于不同的格子,由宝石所构成的集合一定不相同。
有一些格子中间存在一条写着 w 的边,若想通过这条边,则每次需要花费 (i=1∑n(ai−bi)2)×w。其中 ai 和 bi 分别代表边的两端所连接的点的某一种宝石的数量。
注意,这其中总共只有 m 条边。
现在,某人从一个有 s1 个红宝石,s2 个绿宝石,s3 个黄宝石 … sn 个紫宝石的格子上,他想知道到他能走到的所有格子的花费的最小值。特别的,若两个点不联通,那么这两点之间的距离为零,且不能互相到达。
第一行输入两个正整数 n 和 m。
接下来 m 行,每行输入 2n+1 个数字,表示点 u、v 的坐标(同时也分别代表宝石数量)以及 w
最后一行输入 n 个整数表示起始格。
一行一个整数 ∑disi 其中 disi 表示起始格到点 i 的最小花费。
2 4
1 1 2 3 2
1 1 4 5 1
4 5 6 6 3
1 1 6 6 1
1 1
75
| 测试点 | n | m | w |
|---|---|---|---|
| 1∼4 | =1 | ≤105 | ≤10 |
| 5 | ≥2 | ≤105 | =0 |
| 6∼10 | ≤5 | ≤103 | ≤5 |
| 11∼20 | ≤10 | ≤105 | ≤10 |
| 对于所有数据,1≤n≤10,1≤m≤105,1≤w≤10,1≤ai≤100。 |
#include<bits/stdc++.h>
using namespace std;
const long long inf = 1e18;
const int maxn = 5e5 + 5;
int n, m, tot = 0, cnt = 0;
long long dis[maxn], vis[maxn];
long long to[maxn], val[maxn], nxt[maxn], h[maxn];
struct node {
long long v, w;
friend bool operator < (node a, node b) {
return a.w > b.w;
}
} tmp;
struct dot {
long long a[15];
friend bool operator < (dot a, dot b) {
for(int i = 1; i <= n; i++) {
if(a.a[i] != b.a[i]) {
return a.a[i] < b.a[i];
}
}
return 0;
}
} s;
map< dot, int > Map;
priority_queue<node> q;
long long dist(dot x, dot y, long long w) {
long long sum = 0;
for(int i = 1; i <= n; i++) {
sum += ((x.a[i] - y.a[i]) * (x.a[i] - y.a[i]));
}
return sum * w;
}
void add(long long u, long long v, long long w) {
tot++;
to[tot] = v;
val[tot] = w;
nxt[tot] = h[u];
h[u] = tot;
}
void Dijkstra(int s) {
for(int i = 1; i <= 2 * m; i++) dis[i] = inf, vis[i] = 0;
dis[s] = 0;
tmp.v = s, tmp.w = 0;
q.push(tmp);
while(!q.empty()) {
long long u = q.top().v;
q.pop();
if(vis[u]) continue;
vis[u] = 1;
for(long long i = h[u]; i; i = nxt[i]) {
if(dis[to[i]] > dis[u] + val[i]) {
dis[to[i]] = dis[u] + val[i];
tmp.w = dis[to[i]];
tmp.v = to[i];
q.push(tmp);
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n >> m;
for(int i = 1; i <= m; i++) {
dot u, v;
long long w;
for(int j = 1; j <= n; j++) {
cin >> u.a[j];
}
for(int j = 1; j <= n; j++) {
cin >> v.a[j];
}
if(Map[u] == 0) {
cnt++;
Map[u] = cnt;
}
if(Map[v] == 0) {
cnt++;
Map[v] = cnt;
}
cin >> w;
w = dist(u, v, w);
add(Map[u], Map[v], w);
}
for(int i = 1; i <= n; i++) {
cin >> s.a[i];
}
if(Map[s] == 0) cnt++, Map[s] = cnt;
Dijkstra(Map[s]);
long long ans = 0;
for(int i = 1; i <= 2 * m; i++) {
if(dis[i] != inf) {
ans += dis[i];
}
}
cout << ans << endl;
}
求条,谢谢。
所有关注会在当日内派送完毕。