Negative ring ----------- word ring

We have nn strings, and each string is composed of a ~ za ~ z lowercase English letters.
If the last two characters of the string AA exactly match the first two characters of the string BB, then we say that AA and BB can be connected (note: AA can be connected to BB does not mean that BB can be connected to AA).
We want to find some from a given string so that they are connected end to end to form a ring string (a string is also connected end to end), and we want to maximize the average length of this ring string.
The following example:
ababc
bckjaca
caahoynaab

The first string can be connected to the second string, the second string can be connected to the third string, the third string can be connected to the first string, and we connect in this order to form a ring string, length It is 5 + 7 + 10 = 225 + 7 + 10 = 22 (the repeated part is counted twice), 33 strings are used in total, so the average length is 223≈7.33223≈7.33
Input format
There are multiple sets of data for this question.
The first line of each group of data, an integer nn, represents the number of strings; the
next nn lines, each line is a string of less than or equal to 10001000.
Reading in ends with n = 0n = 0.
Output format
If there is no ring string, output "No solution", otherwise the average length of the longest ring string is output.
As long as the difference between the answer and the standard answer does not exceed 0.010.01, the answer is considered correct.
Data range
1≤n≤1051≤n≤105
Input Sample:
. 3
intercommunicational
alkylbenzenesulfonate
tetraiodophenolphthalein
0

Sample output:
21.66

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 700, M = 100010;
int n;
int h[N], e[M], w[M], ne[M], idx;
double dist[N];
int q[N], cnt[N];
bool st[N];
void add(int a, int b, int c){
 e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}
bool check(double mid){
 memset(st, 0, sizeof st);
 memset(cnt, 0, sizeof cnt);
  int hh = 0, tt = 0;
 for (int i = 0; i < 676; i ++){
  q[tt ++] = i;
  st[i] = true;
 }
  int count = 0;
 while(hh != tt){
  int t = q[hh ++];
  if (hh == N)   hh = 0;
  st[t] = false;
    for (int i = h[t]; ~i; i = ne[i]){
   int j = e[i];
   if (dist[j] < dist[t] + w[i] - mid){
    dist[j] = dist[t] + w[i] - mid;
    cnt[j] = cnt[t] + 1;
    if (++ count > 10000)   return true;
    if (cnt[j] >= N)        return true;
    if (!st[j]){
     q[tt ++] = j;
     if (tt == N)  tt = 0;
     st[j] = true;
    }
   }
  }
 }
  return false;
}
int main(){
 char str[1010];
  while(scanf("%d", &n), n){
  memset(h, -1, sizeof h);
  idx = 0;
  for (int i = 0; i < n; i ++){
   scanf("%s", str);
   int len = strlen(str);
   if (len >= 2){
    int left = (str[0] - 'a') * 26 + str[1] - 'a';
    int right = (str[len - 2] - 'a') * 26 + str[len - 1] - 'a';
    add(left, right, len);
    }
  }
    if (!check(0))   puts("No solution");
  else{
   double l = 0, r = 1000;
   while(r - l > 1e-4){
    double mid = (l + r) / 2;
    if (check(mid))   l = mid;
    else              r = mid;
   }
   printf("%lf\n",l);
  }
 }
  return 0;
}
164 original articles published · Like 112 · Visits 6767

Guess you like

Origin blog.csdn.net/qq_45772483/article/details/105479112