ecnu3247(铁路修复计划)

题目链接:http://acm.ecnu.edu.cn/problem/3247/

显然,倍数越大最小生成树就越大,那么久二分答案好了。

为了防止每次kruskal的时候都要排序二导致复杂度升高,把边分成国内和国外两部分,分别排序,在 kruskal 的时候归并一下。

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <algorithm>
using namespace std;

const int maxn = 1e5 + 10;

typedef long long ll;

struct Edge
{
    int u, v, w;
    Edge(int u, int v, int w):u(u), v(v), w(w) {}
};
vector<Edge> edges;
int f[maxn];
int fa[maxn];
int d[2][maxn];
double t[maxn];
int cnt[2] = {0,0};
int n, m;
ll M;

int cmp(int a, int b)
{
    return edges[a].w < edges[b].w;
}

int Find(int x)
{
    if (fa[x] == x)
        return fa[x];
    fa[x] = Find(fa[x]);
    return fa[x];
}

double kruskal(double k)
{
    for (int i=1; i<=n; i++) fa[i] = i;
    for (int i=0; i<cnt[0]; i++) t[d[0][i]] = (double)edges[d[0][i]].w;
    for (int i=0; i<cnt[1]; i++) t[d[1][i]] = (double)edges[d[1][i]].w * k;

    int i0 = 0;
    int i1 = 0;
    double ret = 0;
    while (i0 < cnt[0] || i1 < cnt[1]) //归并
    {
        int tmp = 0;
        if (i0 == cnt[0]) tmp = d[1][i1++];
        else if (i1 == cnt[1]) tmp = d[0][i0++];
        else
        {
            if (t[d[0][i0]] < t[d[1][i1]])
                tmp = d[0][i0++];
            else
                tmp = d[1][i1++];
        }

        int fu = Find(edges[tmp].u);
        int fv = Find(edges[tmp].v);
        if (fu != fv)
        {
            ret += t[tmp];
            fa[fu] = fv;
        }
    }
    return ret;
}

int main()
{
    scanf("%d%d%lld", &n, &m, &M);
    for (int i=0; i<m; i++)
    {
        int u, v, w;
        scanf("%d%d%d%d", &u,&v,&w,&f[i]);
        edges.push_back(Edge(u,v,w));
        d[f[i]][cnt[f[i]]++] = i;
    }

    sort(d[0], d[0]+cnt[0],cmp);
    sort(d[1], d[1]+cnt[1],cmp);

    double l = 1, r = 1e15;
    while (r-l > 0.0000001)
    {
        double mid = (l+r) / 2.0;
        double mst = kruskal(mid);
        if (mst < (double)M)
            l = mid;
        else
            r = mid;
    }
    printf("%.6lf\n", l);

    return 0;
}


猜你喜欢

转载自blog.csdn.net/qust1508060414/article/details/72489622