1486: [HNOI2009]最小圈 二分+dfs

来源:互联网 发布:网络 第二办公室 编辑:程序博客网 时间:2024/05/22 16:54

Description

 

Input

Output

Sample Input

4 5
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;}


原创粉丝点击