码迷,mamicode.com
首页 > 其他好文 > 详细

【bzoj2654】tree

时间:2017-04-22 00:15:18      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:nbsp   方案   cdb   pac   sam   表示   turn   etc   端点   

 

Description

给你一个无向带权连通图,每条边是黑色或白色。让你求一棵最小权的恰好有need条白色边的生成树。
题目保证有解。

 

Input

第一行V,E,need分别表示点数,边数和需要的白色边数。
接下来E行,每行s,t,c,col表示这边的端点(点从0开始标号),边权,颜色(0白色1黑色)。

 

Output

一行表示所求生成树的边权和。
V<=50000,E<=100000,所有数据边权为[1,100]中的正整数。

 

 

Sample Input

2 2 1
0 1 1 1
0 1 2 0

Sample Output

2

 
这题挺有趣的
我们先不考虑白边的限制,那么就是一个最小生成树。
那么我们考虑限制白边数量为一,我们对执行最小生成树的方案做修改:把白边的边权增加。这样就会尽量少地添加白边。
然后我们考虑增加白边的数量,二分即可。
技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int N=100050;
struct Edge{
    int from,to,val,col;
}edge[N];
int from[N],to[N],val[N],col[N];
int fa[N];
int n,m,Need,ans,tot,cnt;
inline void read(int &s){
    int flag=1;s=0;char ch=getchar();
    while(ch<0 || ch>9){if(ch==-)flag=-1;ch=getchar();}
    while(ch>=0 && ch<=9){s=s*10+ch-0;ch=getchar();}
    s*=flag;
}
inline bool operator < (const Edge &a,const Edge &b){return a.val==b.val ? a.col<b.col : a.val<b.val;}
int find(int x){return x==fa[x] ? fa[x] : fa[x]=find(fa[x]);}
bool check(int x){
    tot=cnt=0;
    for(int i=1;i<=n;++i)fa[i]=i;
    for(int i=1;i<=m;++i){
        edge[i].from=from[i];edge[i].to=to[i];edge[i].val=val[i];edge[i].col=col[i];
        if(!col[i])edge[i].val+=x;
    }
    sort(edge+1,edge+m+1);
    for(int i=1;i<=m;++i){
        int fx=find(edge[i].from),fy=find(edge[i].to);
        if(fx!=fy){
            fa[fx]=fy;
            tot+=edge[i].val;
            if(!edge[i].col)++cnt;
        }
    }
    return cnt>=Need;
}
int main(){
    read(n);read(m);read(Need);
    for(int i=1;i<=m;++i){
        read(from[i]);read(to[i]);read(val[i]);read(col[i]);
        ++from[i];++to[i];
    }
    int l=-105,r=105;
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid))l=mid+1,ans=tot-Need*mid;
        else r=mid-1;
    }
    printf("%d\n",ans);
    return 0;
}
bzoj2654

 

【bzoj2654】tree

标签:nbsp   方案   cdb   pac   sam   表示   turn   etc   端点   

原文地址:http://www.cnblogs.com/cygol/p/6746410.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!