Tree (through a cross training exercise test Tsinghua ||)

tree

Memory limit: 512 MiB time limit: 3000 ms standard output
Question Types: traditional evaluation methods: text comparison
 

Title Description

You give a free communication to FIG weighted, each edge is black or white. Let you find a minimum spanning tree need exactly the right edge of the white stripe. Topic guarantee solvable.

Input Format

The first line V, E, need points, respectively, the number of edges and the number of required white edges.
Next E lines of s, t, c, col represents a side end (reference point from 0), the right side, color (Black 0 White 1).

Output Format

Row represents the right side asked for and spanning tree.
V <= 50000, E <= 100000, all data edge weight being a positive integer [1100] of.

Sample

Sample input

2 2 1
0 1 1 1
0 1 2 0

Sample Output

2

Data range and tips

The original data error, has been updated by liutian, but did not retest --- 2016.6.24

Is a is a more metaphysical questions

Half the answer, we have to consider white edge bonuses or impairment, it will correspond to the selected small white side or black side less choice

So if the current white edge if kuskal + mid selected white edge than to the need to continue the above value, if less than the selected white side down on the need for impairment

Because certain kuskal FIG ensure communication, and minimum cost. Therefore, to ensure the correctness

#include<bits/stdc++.h>
#define ll long long
#define A 10000000
using namespace std;
struct edge{
    ll x,y,z,id;
    ll flag;
}e[A];
ll n,m,need,fa[A],zong,ans,end[A];
inline ll read()
{
    ll f=1,x=0;char c=getchar();
    while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return f*x;
}
ll find(ll x)
{
    if(fa[x]!=x) fa[x]=find(fa[x]);
    return fa[x];
}
void hebing(ll x,ll y)
{
    x=find(x),y=find(y);    if(x!=y) fa[y]=x;
}
bool cmp(edge a,edge b){return (a.z==b.z)?(a.flag<b.flag):(a.z<b.z);}
inline void kuskar(ll mid)
{
    for(ll i=0;i<=n;i++)
        fa[i]=i;
    zong=0,ans=0;
    for(ll i=1;i<=m;i++)
    if(!e[i].flag)
        e[i].z+=mid;
    sort(e+1,e+m+1,cmp);
    for(ll i=1;i<=m;i++)
    {
        if(find(e[i].x)!=find(e[i].y))
        {
            if(!e[i].flag)
                zong++;
            hebing(e[i].x,e[i].y);
            ans+=e[i].z;
        }
    }
    for(ll i=1;i<=m;i++)
        if(!e[i].flag)
            e[i].z-=mid;
}
int main()
{
    ll tot=0;
    n=read(),m=read(),need=read();
    for(ll i=1;i<=m;i++)
        e[i].x=read(),e[i].y=read(),e[i].z=read(),e[i].flag=read();
    ll l=-100,r=100;
    while(l<=r)
    {
        ll mid=(l+r)>>1;
        kuskar(mid);
        if(zong>=need) l=mid+1,tot=ans-need*mid;
        else r=mid-1;
    }
    cout<<tot<<endl;
}
View Code

 

Guess you like

Origin www.cnblogs.com/znsbc-13/p/11202606.html