• hdu4253 二分+MST (经典模型)


    n个点,m条边,边分为A,B两类,要构造一棵最小生成树,且树中A边数量为k。

    我们可以通过给所有A边加上权值dx来控制树中A边的数量。显然,当dx增大,A边数量kk会减少。

    二分dx,

    当kk>=k,增大dx(即l=mid+1),同时更新ans=sum(mst)-mid*k;

     当kk<k,减小dx(即r=mid-1)。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 struct node
      6 {
      7     int u,v,w;
      8 }ey[110000],el[110000];
      9 int n,m,k,numey,numel,sset[110000],sum;
     10 const int mmax=1<<30;
     11 int ffind(int x)
     12 {
     13     if(sset[x]==x) return x;
     14     int fa=sset[x];
     15     sset[x]=ffind(fa);
     16     return sset[x];
     17 }
     18 void mmerge(int a,int b)
     19 {
     20     int aa=ffind(a);
     21     int bb=ffind(b);
     22     if(aa!=bb)
     23         sset[aa]=bb;
     24 }
     25 bool cmp(node x1,node y1)
     26 {
     27     return x1.w<y1.w;
     28 }
     29 int kruscal(int dx)
     30 {
     31     int i;
     32     sum=0;
     33     for(i=0;i<=n;i++)
     34         sset[i]=i;
     35     int kk=0,posey=0,posel=0,num=0;
     36     while(posey<numey||posel<numel)
     37     {
     38         int from,to;
     39         if(ey[posey].w+dx<=el[posel].w)
     40         {
     41             from=ffind(ey[posey].u);
     42             to=ffind(ey[posey].v);
     43             if(from!=to)
     44             {
     45                 mmerge(ey[posey].u,ey[posey].v);
     46                 sum+=(ey[posey].w+dx);
     47                 kk++;
     48                 num++;
     49             }
     50             posey++;
     51         }
     52         else
     53         {
     54             from=ffind(el[posel].u);
     55             to=ffind(el[posel].v);
     56             if(from!=to)
     57             {
     58                 mmerge(el[posel].u,el[posel].v);
     59                 sum+=el[posel].w;
     60                 num++;
     61             }
     62             posel++;
     63         }
     64         if(num==n-1) break;
     65     }
     66     if(kk>=k) return 1;
     67     else return 0;
     68 }
     69 int main()
     70 {
     71     int i,casnum=0;
     72     while(scanf("%d%d%d",&n,&m,&k)!=EOF)
     73     {
     74         numey=numel=0;
     75         for(i=0;i<m;i++)
     76         {
     77             int a,b,c,tmp;
     78             scanf("%d%d%d%d",&a,&b,&c,&tmp);
     79             if(tmp==0)
     80             {
     81                 ey[numey].u=a;
     82                 ey[numey].v=b;
     83                 ey[numey++].w=c;
     84             }
     85             else
     86             {
     87                 el[numel].u=a;
     88                 el[numel].v=b;
     89                 el[numel++].w=c;
     90             }
     91         }
     92         sort(ey,ey+numey,cmp);
     93         sort(el,el+numel,cmp);
     94         ey[numey].w=el[numel].w=mmax;
     95         int l=-100,r=100,mid,ans=0;
     96         while(l<=r)
     97         {
     98             mid=(l+r)/2;
     99             if(kruscal(mid))
    100             {
    101                 l=mid+1;
    102                 ans=sum-mid*k;
    103             }
    104             else r=mid-1;
    105         }
    106         printf("Case %d: %d
    ",++casnum,ans);
    107     }
    108     return 0;
    109 }
  • 相关阅读:
    case1.将文件夹内文件,按文件后缀不同进行分类
    openpyxl/csv--python处理excel表格模块
    pyttsx3--文字转语音库
    网络爬虫遵守规则
    python-requests库
    js 对象遍历出现的异常
    POI解析word文件,并为特定规则的key替换值
    bootstrap-table获得页面加载数据
    Javaweb项目下载文件时设置文件名
    MySQL自定义函数
  • 原文地址:https://www.cnblogs.com/mt522/p/5349956.html
Copyright © 2020-2023  润新知