主要难在构图上,很麻烦。用的Floyd 110ms
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#include <vector>
#include <set>
using namespace std;
#define RMAX 210
int G[RMAX][RMAX];
set<int> person[30]; //每个人所相邻的区域
int personat[30]; // 每个人所在 TOWN 的编号
map<int, int> town; //城市 到人的映射
int rn, tn,l;
typedef pair<int, int> pii;
map<pii, int> v;
struct ed{
int ll, rr;// 每条边只能关联两个Region
int u, v; //顶点
}edge[50000];
int main(){
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
scanf("%d %d %d", &rn, &tn, &l);
int nu;
for (int i = 0; i < l; i++){
scanf("%d", &nu);
personat[i] = --nu;
town[nu] = i;
}
int x, y, start;
int ecnt = 0;
for (int i = 0; i < rn; i++){
scanf("%d", &nu);
scanf("%d", &start);
start--;
x = start;
for (int j = 1; j < nu; j++){
scanf("%d", &y);
y--;
int a = x, b = y;
if (a > b)a^=b, b^=a, a^=b;
if (!v.count(pii(a, b))){
v[pii(a, b)] = ecnt;
edge[ecnt].ll = i;
edge[ecnt].u = a, edge[ecnt].v = b;
ecnt++;
}
else{
edge[v[pii(a, b)]].rr = i;
}
x = y;
}
y = start;
int a = x, b = y;
if (a > b)a^=b, b^=a, a^=b;
if (!v.count(pii(a, b))){
v[pii(a, b)] = ecnt;
edge[ecnt].ll = i ;
edge[ecnt].u = a, edge[ecnt].v = b;
ecnt++;
}
else{
edge[v[pii(a, b)]].rr = i;
}
}
memset(G, 0x3f, sizeof(G));
for (int i = 0; i < ecnt; i++){
G[edge[i].ll][edge[i].rr] = G[edge[i].rr][edge[i].ll] = 1;
if (town.count(edge[i].u) ){
if (!person[town[edge[i].u]].count(edge[i].ll)){
person[town[edge[i].u]].insert(edge[i].ll);
}
if (!person[town[edge[i].u]].count(edge[i].rr)){
person[town[edge[i].u]].insert(edge[i].rr);
}
}
if (town.count(edge[i].v) ){
if (!person[town[edge[i].v]].count(edge[i].ll)){
person[town[edge[i].v]].insert(edge[i].ll);
}
if (!person[town[edge[i].v]].count(edge[i].rr)){
person[town[edge[i].v]].insert(edge[i].rr);
}
}
}
for (int i = 0; i < rn; i++)
G[i][i] = 0;
for (int k = 0; k < rn; k++)
for (int i = 0; i < rn; i++)
for (int j = 0; j < rn; j++)
G[i][j] = min(G[i][j], G[i][k] + G[k][j]);
int ans = 100000000;
for (int i = 0; i < rn; i++){
int res = 0;
for (int j = 0; j < l; j++){
int MIN = 100000000;
for (set<int>::const_iterator it = person[j].begin(); it != person[j].end(); it++){
MIN = min(MIN, G[*it][i]);
}
res += MIN;
}
ans = min(ans, res);
}
printf("%d\n", ans);
return 0;
}