题意很简单,求所有两点间最短路的最大值。
暴力n次spfa。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
using namespace std;
#define maxn 1111
#define maxm 21111
#define INF 111111111
struct node {
int v, w;
node (int v = 0, int w = 0) : v(v), w(w) {}
};
vector <node> edge[maxn];
int n, cnt[maxn];
bool vis[maxn];
string name, name2;
map <string, int> gg;
int ans, cur;
int d[maxn];
int fa[maxn];
int find (int x) {
return fa[x] == x ? fa[x] : fa[x] = find (fa[x]);
}
void add_edge (int from, int to, int w) {
edge[from].push_back (node (to, w));
}
bool spfa (int start) {
memset (vis, 0, sizeof vis);
for (int i = 1; i <= n; i++)
d[i] = INF;
vis[start] = 1; d[start] = 0;
queue <int> que;
while (!que.empty ())
que.pop ();
memset (cnt, 0, sizeof cnt);
cnt[start] = 1;
que.push (start);
while (!que.empty ()) {
int u = que.front (); que.pop ();
vis[u] = 0;
for (int i = 0; i < edge[u].size (); i++) {
int v = edge[u][i].v;
if (d[v] > d[u]+edge[u][i].w) {
d[v] = d[u]+edge[u][i].w;
if (!vis[v]) {
vis[v] = 1;
que.push (v);
if (++cnt[v] > n)
return 0;
}
}
}
}
cur = 0;
for (int i = 1; i <= n; i++) {
cur = max (cur, d[i]);
}
ans = max (cur, ans);
return 1;
}
int main () {
//freopen ("in", "r", stdin);
while (scanf ("%d", &n) == 1 && n) {
gg.clear ();
for (int i = 1; i <= n; i++)
fa[i] = i, edge[i].clear ();
for (int i = 1; i <= n; i++) {
cin >> name;
gg[name] = i;
}
int q;
scanf ("%d", &q);
while (q--) {
cin >> name >> name2;
int u = gg[name], v = gg[name2];
add_edge (u, v, 1);
add_edge (v, u, 1);
int p1 = find (u), p2 = find (v);
if (p1 != p2) {
fa[p1] = p2;
}
}
int kk = find (1);
for (int i = 2; i <= n; i++) {
if (find (i) != kk) {
printf ("-1\n");
goto out;
}
}
ans = 0;
for (int i = 1; i <= n; i++)
spfa (i);
printf ("%d\n", ans);
out: ;
}
return 0;
}