Description
Input
Output
Sample Input
4 5
1 2 5
2 3 5
3 1 5
2 4 3
4 1 3
1 2 5
2 3 5
3 1 5
2 4 3
4 1 3
Sample Output
3.66666667
这题直接dfs计算好像有点难,但可以换个角度,我们可以二分最小圈平均值,让每条边减去这个值,如果存在负值环就说明还有更小的,然后再用dfs来判断就行了。
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
using namespace std;
struct node
{
int v;
double w;
};
const int maxm = 100005;
vector<node>v[maxm];
int vis[maxm], x[maxm], y[maxm], flag;
double z[maxm], dis[maxm];
void dfs(int k);
int main()
{
int n, i, j, k, sum, m;
scanf("%d%d", &n, &m);
for (i = 1;i <= m;i++)
scanf("%d%d%lf", &x[i], &y[i], &z[i]);
double ans, l=-10000000, r=10000000;
while (r - l > 1e-9)
{
double mid = (r + l) / 2;
for (i = 1;i <= n;i++)
v[i].clear();
for (i = 1;i <= m;i++)
{
node temp;
temp.v = y[i], temp.w = z[i] - mid;
v[x[i]].push_back(temp);
}
flag = 0;
memset(vis, 0, sizeof(vis));
memset(dis, 0, sizeof(dis));
for (i = 1;i <= n;i++)
{
dfs(i);
if (flag) break;
}
if (flag) r = mid, ans = mid;
else l = mid;
}
printf("%.8f\n", ans);
return 0;
}
void dfs(int k)
{
vis[k] = 1;
for (int i = 0;i < v[k].size();i++)
{
node temp = v[k][i];
if (dis[temp.v] > dis[k] + temp.w)
{
if (vis[temp.v])
{
flag = 1;
return;
}
dis[temp.v] = dis[k] + temp.w;
dfs(temp.v);
if (flag) return;
}
}
vis[k] = 0;
}