zoukankan      html  css  js  c++  java
  • bzoj2654

    二分答案 给白色的边加上边权使刚刚好取到need条

    这个二分是靠有右的。。。。

     1 #include<bits/stdc++.h>
     2 #define clr(a,x) memset(a,x,sizeof(a))
     3 #define rep(i,l,r) for(int i=l;i<r;i++)
     4 typedef long long ll;
     5 using namespace std;
     6 int read()
     7 {
     8     char c=getchar();
     9     int ans1=0,f=1;
    10     while(!isdigit(c)){
    11         if(c=='-') f=-1;
    12         c=getchar();
    13     }
    14     while(isdigit(c)){
    15         ans1=ans1*10+c-'0';
    16         c=getchar();
    17     }
    18     return ans1*f;
    19 }
    20 struct edge{
    21     int d,v,from,to,p;
    22     inline bool operator <(const edge&A)const{
    23         return v<A.v||(v==A.v&&p<A.p);
    24     }
    25 };
    26 const int maxn=500005,maxm=100005;
    27 edge e[maxm];
    28 int f[maxn],n,m,need;
    29 int find(int a)
    30 {
    31     return f[a]==a?f[a]:f[a]=find(f[a]);
    32 }
    33 int kruskal(int a)
    34 {    
    35     int cnt=0,ans=0;
    36     rep(i,0,n) f[i]=i;
    37     rep(i,0,m){
    38         if(!e[i].p) e[i].v=e[i].d+a;
    39         else e[i].v=e[i].d;
    40     }
    41     sort(e,e+m);
    42     rep(i,0,m){
    43         if(find(e[i].from)!=find(e[i].to)){
    44             f[find(e[i].from)]=find(e[i].to);
    45             if(!e[i].p) cnt++;
    46             ans+=e[i].v;
    47         }
    48     }
    49     return cnt>=need?ans:-1;
    50 }
    51 int erfen(int l,int r)
    52 {    
    53     if(l==r) return l;
    54     int mid=(l+r+1)>>1;
    55     int x=kruskal(mid);
    56     if(x==-1) return erfen(l,mid-1);
    57     return erfen(mid,r);
    58 }
    59 int main()
    60 {
    61     n=read(),m=read(),need=read();
    62     rep(i,0,m){
    63         e[i].from=read(),e[i].to=read(),e[i].d=read(),e[i].p=read();
    64     }
    65     int k=erfen(-500,500);
    66     printf("%d
    ",kruskal(k)-need*k);
    67     return 0;
    68 }
    View Code

    2654: tree

    Time Limit: 30 Sec  Memory Limit: 512 MB
    Submit: 614  Solved: 228
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

      一行表示所求生成树的边权和。

    Sample Input

    2 2 1
    0 1 1 1
    0 1 2 0


    Sample Output

    2

    HINT

    数据规模和约定

      0:V<=10

      1,2,3:V<=15

      0,..,19:V<=50000,E<=100000

      所有数据边权为[1,100]中的正整数。

    Source

     
    [Submit][Status][Discuss]
  • 相关阅读:
    java的注解
    java的反射
    Java的垃圾回收机制
    Java的jvm上的内存位置的分配
    Java的Junit与debug模式入门
    三、FreeMarker 模版开发指南 第三章 模版
    【CodeForces】[698A]Vacations
    【CodeForces】[629B]Far Relative’s Problem
    【POJ】[1328]Radar Installation
    【杭电】[1789]Doing Homework again
  • 原文地址:https://www.cnblogs.com/chensiang/p/4675013.html
Copyright © 2011-2022 走看看