求助WQS二分
查看原帖
求助WQS二分
239192
淸梣ling楼主2022/11/29 14:48

已经 AC,但是有个地方不清楚。

#include<bits/stdc++.h>
using namespace std;

struct edge
{
    int x,y,z;
    edge() {}
    edge(int x, int y, int z) : x(x), y(y), z(z) {}
};
struct dsu
{
    int fa[50100];
    void clear(int n) { for(int i=0; i<=n; i++) fa[i]=i; }
    int find(int x) { return x==fa[x] ? fa[x] : fa[x]=find(fa[x]); }
    bool merge(int x, int y)
    {
        int fx=find(x),fy=find(y);
        if(fx==fy) return 0;
        fa[fy]=fx;
        return 1;
    }
};

vector<edge> v1,v2;
dsu u;
int n,m,t;
long long ans;

bool check(int k)
{
    int ans=0;
    int i=0,j=0;

    u.clear(n);
    while(i<v1.size()&&j<v2.size())
    {
        if(v1[i].z<v2[j].z+k)
        u.merge(v1[i].x, v1[i].y), ++i;
        else
        ans+=u.merge(v2[j].x, v2[j].y), ++j;
    }
    while(j<v2.size())
    ans+=u.merge(v2[j].x, v2[j].y), ++j;

    return ans<t;
}
int erfen(int l, int r)
{
    while(l<r)
    {
        int mid=(l+r)>>1;
        if(check(mid+1))
        r=mid;
        else
        l=mid+1;
    }
    return l;
}
bool cmp(const edge &a, const edge &b)
{
    return a.z<b.z;
}
int main()
{
    cin>>n>>m>>t;
    for(int i=1; i<=m; i++)
    {
        int x,y,z,c;
        scanf("%d%d%d%d", &x, &y, &z, &c);
        if(c) v1.emplace_back(x, y, z);
        else v2.emplace_back(x, y, z);
    }

    sort(v1.begin(), v1.end(), cmp);
    sort(v2.begin(), v2.end(), cmp);
    int k=erfen(-100, 100);

    u.clear(n);
    int i=0,j=0;
    while(i<v1.size()&&j<v2.size())
    {
        if(v1[i].z<v2[j].z+k)
        ans+=v1[i].z*u.merge(v1[i].x, v1[i].y), ++i; //
        else
        ans+=(v2[j].z+k)*u.merge(v2[j].x, v2[j].y), ++j;
    }
    while(i<v1.size())
    ans+=v1[i].z*u.merge(v1[i].x, v1[i].y), ++i; //
    while(j<v2.size())
    ans+=(v2[j].z+k)*u.merge(v2[j].x, v2[j].y), ++j;
    cout<<ans-k*t; //
    // 就这几个地方,先是加上 k,后面再减掉,正常来说去掉也是可以的,
    // 但是去掉 40pts,应该是选的个数不是恰好 need 个,请问这是为什么?
    return 0;
}
2022/11/29 14:48
加载中...