zoukankan      html  css  js  c++  java
  • 【BZOJ 2654】 MST

    2654: tree

    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

    【分析】

      嗯?我想不到的题。。如果不断给所有白色边加上同一个值,跑MST(边权相同先选白色边),那么选取的白色边的数量显然是不升的,就这样,最后减掉need*add就好了。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 #define Maxn 50010
     8 #define Maxm 100010
     9 #define INF 0x7fffffff
    10 
    11 int n,m,k;
    12 
    13 int mymin(int x,int y) {return x<y?x:y;}
    14 
    15 struct node
    16 {
    17     int x,y,c,cc,p,next;
    18 }t[Maxm*2];
    19 int first[Maxn],len;
    20 
    21 void ins(int x,int y,int c,int p)
    22 {
    23     t[++len].x=x;t[len].y=y;t[len].cc=t[len].c=c;t[len].p=p;
    24     t[len].next=first[x];first[x]=len;
    25 }
    26 
    27 bool cmp(node x,node y) 
    28 {
    29     if(x.c==y.c) return x.p<y.p;
    30     return x.c<y.c;
    31 }
    32 
    33 int fa[Maxn];
    34 int ffa(int x)
    35 {
    36     if(fa[x]!=x) fa[x]=ffa(fa[x]);
    37     return fa[x];
    38 }
    39 
    40 int tot,now;
    41 void check(int x)
    42 {
    43     tot=0;now=0;
    44     for(int i=1;i<=n;i++) fa[i]=i;
    45     for(int i=1;i<=len;i++) if(!t[i].p) t[i].c=t[i].cc+x;
    46     sort(t+1,t+1+len,cmp);
    47     for(int i=1;i<=len;i++)
    48     {
    49         int x=t[i].x,y=t[i].y;
    50         if(ffa(x)!=ffa(y))
    51         {
    52             fa[ffa(x)]=ffa(y);
    53             if(!t[i].p) tot++;
    54             now+=t[i].c;
    55         }
    56     }
    57 }
    58 
    59 int ffind(int l,int r)
    60 {
    61     int ans=INF;
    62     while(l<=r)
    63     {
    64         int mid=(l+r)>>1;check(mid);
    65         if(tot>=k) ans=now-k*mid,l=mid+1;
    66         else r=mid-1;
    67     }
    68     return ans;
    69 }
    70 
    71 int main()
    72 {
    73     scanf("%d%d%d",&n,&m,&k);
    74     len=0;
    75     memset(first,0,sizeof(first));
    76     int cnt=0;
    77     for(int i=1;i<=m;i++)
    78     {
    79         int x,y,c,p;
    80         scanf("%d%d%d%d",&x,&y,&c,&p);
    81         x++;y++;
    82         if(p==0) cnt++;
    83         ins(x,y,c,p);ins(y,x,c,p);
    84     }
    85     int ans=ffind(-100,100);
    86     if(ans==INF) ans=0;
    87     printf("%d
    ",ans);
    88     return 0;
    89 }
    View Code

    2017-03-08 21:26:50

  • 相关阅读:
    Libevent源码分析系列
    TCP检验和
    Redis—数据结构之list
    STL—list
    STL—vector
    STL—vector空间的动态增长
    STL—内存的配置与释放
    Actuator 未授权访问之heapdump利用
    Git submodule update 命令执行
    利用Haproxy搭建 HTTP 请求走私(Request smuggling)环境
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6523133.html
Copyright © 2011-2022 走看看