POJ 2949 判断负(正)环,经典二分
(2010-09-02 20:51:30)
标签:
poj2949判断负(正)环经典二分it |
分类: 图论 |
题目描述:
给你n个字符串。
如果一个字符串的最后两个字符和另一个字符串的开头两个字符相同的话,那么这两个字符串可以连接。
现在让你连接成一个环(当然,每个字符串只能用一次)。
这个环的平均长度是:环中所有的字符串长度之和 除以 字符串的个数。
输出 最长 的平均长度。
如果不存在,输出 无解。
解题报告:
建图:
单词:intercommunicational
那么就连接in节点 和 al节点,权值为单词的长度。
问题就转化成了:
在图中找环,环的边权相加 除以 边数 就是这个环的平均长度。
但是怎样找到最长的呢?
二分!
注意到:
枚举每一个平均长度mid值。
如果存在一个环,(E1+...+Ek)/k>=mid(其中k是边数,E1……Ek是各个边权),
那么正解比mid大,否则比mid小,这就是二分策略。
那么怎样知道是否存在(E1+...+Ek)/k>=mid 呢?
如下转化:(E1+...+Ek)>=mid*k
E1-mid + E2–mid + E3-mid + ... + Ek-mid >= 0
所以,把所有的边权改为Ei – mid,然后看是否存在正环就可以,存在就是满足条件。
代码如下:
#include<iostream>#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;
#define size 700
#define eps 1e-8
int n, cnt[2];
double dis[size];
struct edge{int from, to; double val;} e[2][100005];
void insert(int from, int to, double va, int id)
{
}
char str[1001];
int judge(char a, char b)
{
}
bool bellman()
{
}
int main()
{