You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
2.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
const int M = 1e5 + 10;
const int U = 26 * 26;
int n;
int h[N], e[M], w[M], ne[M], idx;
double dist[N];
bool st[N]; // 如果当前这个点 u 可以松弛的点 v 是被访问过的,那么就说明一定存在负环。
char str[N]; // 黄海替换为string,结果执行时间由70ms--> 400ms!!!
const double eps = 1e-3;
void add(int a, int b, int c) {
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
bool dfs(int u, double mid) {
if (st[u]) return 1; // 如果又见u说明有环
bool flag = 0; // 我的后代们是不是有环?
st[u] = 1; // u我出现过一次了~
for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i];
// 更新最小值,判负环
if (dist[v] > dist[u] - w[i] + mid) {
dist[v] = dist[u] - w[i] + mid;
// 检查一下我的下一个节点j,它要是有负环检查到,我也汇报
flag = dfs(v, mid);
if (flag) break;
}
}
st[u] = 0; // 回溯
return flag;
}
bool check(double mid) {
memset(dist, 0, sizeof dist);
for (int i = 0; i < U; i++)
if (dfs(i, mid)) return 1;
return 0;
}
void solve() {
memset(h, -1, sizeof h);
idx = 0;
while (n--) {
scanf("%s", str);
int len = strlen(str);
if (len < 2) continue;
int a = (str[0] - 'a') * 26 + str[1] - 'a';
int b = (str[len - 2] - 'a') * 26 + str[len - 1] - 'a';
add(a, b, len);
}
double l = 0, r = 1e3;
while (r - l > eps) {
double mid = (l + r) / 2;
if (check(mid))
l = mid;
else
r = mid;
}
if (l < eps)
puts("No solution");
else
printf("%.2lf\n", r);
}
int main() {
// 多组测试数组喜欢单开一个solve()进行处理,确实看着舒服
while (scanf("%d", &n), n) solve();
return 0;
}