【TOJ 2433】Word Rings【SPFA+二分】
2014-07-27 10:25
295 查看
题意:给出n个字符串,字符串衔接的方式是前两个字母和后两个字母相同,问连成一个环的平均长度最大是多少。
思路:我们二分这个平均长度len,假设m个边连成一个环,每条边的长度分别是l1.l2.l3...lm,则∑li / m = len;,即存在一个环使得∑li >= len*m 把式子经过整理之后得到
∑li-len >= 0因而转化成判断是否存在一个正环,可以用spfa判断。注意的是这里要建一个超级节点,使得整个图是联通的。
思路:我们二分这个平均长度len,假设m个边连成一个环,每条边的长度分别是l1.l2.l3...lm,则∑li / m = len;,即存在一个环使得∑li >= len*m 把式子经过整理之后得到
∑li-len >= 0因而转化成判断是否存在一个正环,可以用spfa判断。注意的是这里要建一个超级节点,使得整个图是联通的。
#include <cmath> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; #define N 100004 #define inf 0x3f3f3f3f #define vn 26*26 #define eps 1e-9 struct E { int v, ne; double d; E(){} E(int _v, double _d, int _ne): v(_v), d(_d), ne(_ne){} }e ; int size, head[800]; int mp[26*30][26*30]; int init() { size = 0; memset(head, -1, sizeof(head)); } void add(int u, int v, double d) { e[size] = E(v, d, head[u]); head[u] = size++; } char w[1004]; double dis[vn+100]; bool vis[vn+100]; int cnt[vn+100]; queue<int>Q; bool spfa(double mid) { memset(vis, false, sizeof(vis)); int i, v, j, u; double d; for (i = 0;i <= vn;i++) { dis[i] = -inf; } memset(cnt, 0, sizeof(cnt)); while (!Q.empty()) Q.pop(); Q.push(0), dis[0] = 0; vis[0] = true;cnt[0]++; while (!Q.empty()) { u = Q.front(); Q.pop(), vis[u] = false; for (i = head[u];~i;i = e[i].ne) { v = e[i].v, d = e[i].d-mid; if (dis[v] < dis[u]+d) { dis[v] = dis[u]+d; cnt[v]++; if (cnt[v] > vn) return true; if (!vis[v]) vis[v] = true, Q.push(v); } } } return false; } int main() { int n, i, j, len; while (scanf("%d", &n), n) { memset(mp, 0, sizeof(mp)); init(); int tm, tv, mx = 0; for (i = 0;i < n;i++) { scanf("%s", w); len = strlen(w); if (len < 2) continue; mx = max(len, mx); tm = (w[0]-'a')*26+(w[1]-'a')+1, tv = (w[len-2]-'a')*26+(w[len-1]-'a')+1; mp[tm][tv] = max(mp[tm][tv], len); } for (i = 1;i <= vn;i++) { for (j = 1;j <= vn;j++) { if (mp[i][j]) add(i, j, mp[i][j]*1.0); } add(0, i, 0); } if (!spfa(0)) { puts("NO solution.");continue;} double f, r, mid; f = 0, r = mx*1.0; while (fabs(f-r) > eps) { mid = (f+r)*0.5; if (spfa(mid)) f = mid; else r = mid; } printf("%.2lf\n", f); } }
相关文章推荐
- hdu 2962 Trucking【二分+SPFA】
- [bzoj2709][Violet 1]迷宫花园(二分+spfa)
- UVA 11090 Going in Cycle!! 环平均权值(bellman-ford,spfa,二分)
- UVA11090 Going in Cycle!! (二分+SPFA判断有无负权)
- hdu 1839 Delay Constrained Maximum Capacity Path(spfa+二分)
- hdu1839—Delay Constrained Maximum Capacity Path(spfa+二分)
- UVALive 4223 Trucking 二分+spfa
- poj 3621 二分+spfa
- 二分查找+spfa(洛谷1948 [USACO08JAN]电话线Telephone Lines) 4000
- UVA11090 Going in Cycle!! 解题报告【判负环】【SPFA】【二分答案】
- [Usaco2007 Dec][BZOJ1690] 奶牛的旅行|分数规划|二分|SPFA
- POJ 3621 Sightseeing Cows(01分数规划+二分+spfa判负环)
- UVA11090 Going in Cycle!! (二分+SPFA推断有无负权)
- UVALive 4223 / HDU 2962 spfa + 二分
- poj 3621 二分+spfa
- 二分+SPFA--poj3662
- HDU-1839-二分下限+spfa
- 洛谷1462 通往奥格瑞玛的道路 二分+spfa
- TOJ 3875 Flowerpot -- RMQ + 二分
- bzoj2709 [Violet 1]迷宫花园 二分+spfa