题目链接:http://codeforces.com/problemset/problem/703/B
题意:
input
4 1 2 3 1 2 3
output
17
第二行每个城市的魅力值,第三行k个首都的编号从1开始。
每个编号相邻的城市都有一条路,第一个点和最后一个点也有一条路,即 1 — 2 — ... — n — 1。
此外每个首都和其他任何点之间都有一条路。
每两个城市之间最多一条路。
每条路花费为两个城市魅力值相乘。
问走完每条路要花多少钱。
先考虑首都,算的时候注意去重,同时标记已经访问过的每个首都。
然后在每个非首都的城市建立两条路,但是要看这两条路是否已经存在了,也就是说要看每个非首都节点编号相邻的两个节点是否为首都或已经访问过。不是的话就加上。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
int c[100100], vis[100100];
int main() {
int n, k;
int i;
scanf("%d %d", &n, &k);
ll sum = 0, ans = 0;
for(i = 0; i < n; i++) {
scanf("%d", c + i);
sum += c[i]; //预处理存下所有节点魅力值和
}
int cap, tmp = 0;
memset(vis, 0, sizeof vis);
for(i = 0; i < k; i++) {
scanf("%d", &cap);
cap--;
//tmp是之前所有首都的魅力值和,和这些点一定都有路了,所以不用再加
ans += (sum - c[cap] - tmp) * c[cap];
tmp += c[cap];
vis[cap] = 1;
}
for(i = 0; i < n; i++) {
if(vis[i] == 0) {
if(vis[(i + 1) % n] == 0) ans += c[(i + 1) % n] * c[i]; //不是首都或没访问过则加上路
if(vis[(i - 1 + n) % n] == 0) ans += c[(i - 1 + n) % n] * c[i];
vis[i] = 1;
}
}
printf("%I64d\n", ans);
return 0;
}