zoukankan      html  css  js  c++  java
  • BZOJ 2654 tree

    2654: tree

    Time Limit: 30 Sec  Memory Limit: 512 MB
    Submit: 2600  Solved: 1069
    [Submit][Status][Discuss]

    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

    HINT

    原数据出错,现已更新 by liutian,但未重测---2016.6.24

    Source

    二分+kruskal

    给白色边都加上一个值,做mst会使得选取的白边数量减少,所以可以二分它

    #include <bits/stdc++.h>
    using namespace std;
    inline int read()
    {
     int x=0;int f=1;char ch=getchar();
     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
     return x*f;
    }
    const int MAXN=1e6+10;
    int fa[MAXN],ans,n,m,need,xx[MAXN],yy[MAXN],vv[MAXN],flag[MAXN],cnt,tot;
    struct node{
     int x,y,v,flag;
    }e[MAXN];
    int getfather(int st){
     return fa[st]==st?st:fa[st]=getfather(fa[st]);
    }
    bool mycmp(node n,node m){
     return n.v<m.v||(n.v==m.v&&n.flag<m.flag);
    }
    void init(){
      n=read();m=read();need=read();
      for(int i=1;i<=m;i++){
       xx[i]=read();yy[i]=read();vv[i]=read();flag[i]=read();
      }
    }
    bool check(int x){
     cnt=0;
     tot=0;
     for(int i=0;i<n;i++){
      fa[i]=i;
     }
     for(int i=1;i<=m;i++){
      e[i].x=xx[i];e[i].y=yy[i];e[i].v=vv[i];e[i].flag=flag[i];
      if(!flag[i]) e[i].v+=x;
     }
     sort(e+1,e+m+1,mycmp);
     for(int i=1;i<=m;i++){
      int xx=e[i].x;int yy=e[i].y;
      int tx=getfather(xx);int ty=getfather(yy);
      if(tx!=ty) {fa[tx]=ty;if(!e[i].flag) cnt++;tot+=e[i].v;} 
     }
     return cnt>=need;
    }
    void solve(){
     int l=-105;int r=105;
     int ans;
     while(l<=r){
      int mid=(r+l)>>1;
      if(check(mid)) ans=tot-cnt*mid,l=mid+1;
      else r=mid-1; 
     }
     cout<<ans<<endl;
    }
    int main(){
      init();
      solve();
      return 0;
    }
    

      

  • 相关阅读:
    sql语句之case when null 解决方法
    sql server分组按顺序编号(转+补充)
    非IE用window.open弹出窗口并向父窗口传值
    IE6浏览器弹出窗口,父窗口传值
    sql之储存过程与函数的区别
    sql之执行事务性语句
    c#获取与筛选对象相匹配的所有DataRow对象数组
    ?: 运算符(C# 参考)
    Mysql 5.7优化
    libcurl.a 跨平台
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/8086840.html
Copyright © 2011-2022 走看看