一个图,边分为黑边和白边,白边最多能选择k条,并且要保持图连通的情况下,求一个权值和最大的子图

首先贪心的想的话,肯定是要把黑边全选上(因为边权无负值),选完所有黑边之后并查集缩点(一直不知道这个操作叫缩点天啊,我是憨憨),然后缩完的图,用白边跑一次最大生成树,
如果k还有剩余,再把刚才没选的白边也加上。一点点就是多样例输入记得清空,莫名其妙(智商掉线)W了几发。。。
struct IN
{
    ll u,v,w;
    IN (ll uu,ll vv,ll ww):u(uu),v(vv),w(ww){}
    bool operator < (IN b)
    {
        return w>b.w;
    }
};
ll fa[MAXN];
ll find(ll x)
{
    return x==fa[x]?x:fa[x]=find(fa[x]);
}
int main()
{
    fast;
    int t;cin>>t;
    while(t--)
    {
        ll n,m,k;  
        cin>>n>>m>>k;
        vector<IN>ed0,ed1,ed2;
        rep(i,m) 
        {
            int x,y,w,c;cin>>x>>y>>w>>c;
            if(c==0) ed0.push_back(IN(x,y,w));
            else ed1.push_back(IN(x,y,w));
        }

        rpp(i,n) fa[i]=i;
        ll ans=0;
        ll cnt=n;
        rep(i,ed0.size())
        {
            ll f1=find(ed0[i].u),f2=find(ed0[i].v);
            if(f1!=f2) fa[f2]=f1,--cnt;//连通块个数减一
            ans+=ed0[i].w;
        }

        sort(all(ed1));
        rep(i,ed1.size())
        {
            if(k==0) break;
            ll f1=find(ed1[i].u),f2=find(ed1[i].v);
            if(f1!=f2) fa[f2]=f1,--cnt,--k,ans+=ed1[i].w;
            else ed2.push_back(ed1[i]);
        }
        sort(all(ed2));
        rep(i,ed2.size())
        {
            if(k==0) break;
            ans+=ed2[i].w;
            --k;
        }

        if(cnt>1) cout<<"-1"<<endl;
        else cout<<ans<<endl;
    }
    return 0;
}