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\n",++casnum,ans);
107     }
108     return 0;
109 }
时间: 2024-12-11 13:46:08

hdu4253 二分+MST (经典模型)的相关文章

【BZOJ 3232】圈地游戏 二分+SPFA判环/最小割经典模型

最小割经典模型指的是“一堆元素进行选取,对于某个元素的取舍有代价或价值,对于某些对元素,选取后会有额外代价或价值”的经典最小割模型,建立倒三角进行最小割.这个二分是显然的,一开始我也是想到了最小割的那个模型的但是我觉得他会不是一个圈我就否掉了,但是仔细想想的话会发现,如果是这样的话所得到的答案一定小于等于一个圈的答案(浓度),所以我们可定会得到最终答案,所以这样做是可以的,所以说要有宽松得正解的意识(泥沙俱下但沙子不影响我泥).当时我否掉最小割以后就立马去想费用流了,然后想到建图后发现那样建图虽

POJ3343&amp;HDU2413Against Mammoths (二分匹配)经典

Against Mammoths Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 316 Accepted Submission(s): 90 Problem Description Back to year 3024, humans finally developed a new technology that enables them t

Topic modeling【经典模型】

http://www.cs.princeton.edu/~blei/topicmodeling.html Topic models are a suite of algorithms that uncover the hidden thematic structure in document collections. These algorithms help us develop new ways to search, browse and summarize large archives o

【神经网络篇】--基于数据集cifa10的经典模型实例

一.前述 本文分享一篇基于数据集cifa10的经典模型架构和代码. 二.代码 import tensorflow as tf import numpy as np import math import time from tutorials.image.cifar10 import cifar10 from tutorials.image.cifar10 import cifar10_input # 本节使用的数据集是CIFAR-10,这是一个经典的数据集,包含60000张32*32的彩色图像,

【Keras篇】---利用keras改写VGG16经典模型在手写数字识别体中的应用

一.前述 VGG16是由16层神经网络构成的经典模型,包括多层卷积,多层全连接层,一般我们改写的时候卷积层基本不动,全连接层从后面几层依次向前改写,因为先改参数较小的. 二.具体 1.因为本文中代码需要依赖OpenCV,所以第一步先安装OpenCV 因为VGG要求输入244*244,而数据集是28*28的,所以需要通过OpenCV在代码里去改变. 2.把模型下载后离线放入用户的管理目录下面,这样训练的时候就不需要从网上再下载了 3.我们保留的是除了全连接的所有层. 4.选择数据生成器,在真正使用

二分答案经典入门题:)

LuoguP1024  一元三次方程求解 题目传送门 因为根与根之间的差不超过1,所以我们就可以分段枚举,又已知根的取值范围是[-100,100],于是就很简单啦QWQ xiu-代码走起-- 1 #include<cstdio> 2 double a,b,c,d; 3 double count(double x){//计算函数值 4 return a*x*x*x+b*x*x+c*x+d; 5 } 6 int main(){ 7 double l,r,mid,x1,x2; 8 int tot=0

hdu4253 Two Famous Companies --- 二分+MST

给n个点,m条边的图,每条边要么属于a公司,要么属于b公司.要求一颗最小生成树,条件是其中属于a公司的边数为k. 这题做法很巧妙. 要求最小生成树,但有一定限制,搜索.贪心显然都不对. 要是能找到一种合理的控制方法,使得求MST的过程中可以控制a公司边的数量,那样问题就解决了. 所以我们可以人为给a公司的边加上一定的权值,使得其中一些边不得不退出MST的选择范围内. 如果此时求的mst里a公司的边数>k,那么就要增加权值:边数<k时,权值为负. 所以,通过二分边权值,可以使得求得mst里所含a

BZOJ 2654 &amp; 玄学二分+MST

题意: 给一张图,边带权且带颜色黑白,求出一棵至少包含k条白边的MST SOL: 正常人都想优先加黑边或者是白边,我也是这么想的...你看先用白边搞一棵k条边的MST...然后维护比较黑边跟白边像堆一样慢慢往里面加...不过讲课的时候跟原题有点出入...这里只有k条边好像比较难维护... 正解也非常巧妙...首先如果有一棵MST,他所含白边数量多于k,那么我们如果可以适当增加白边的边权那么我们就可以减少它的边而且达到最优....想想很有道理你让我证明那有点日了狗了... 然后我们就二分白边的增加

【LA3487】最小割-经典模型 两种方法

题目链接 题意:A.B两个公司要买一些资源(他们自己买的资源不会重复),一个资源只能卖给一个公司.问最大收益. simple input 部分: 54 1 //买到1就给54元 15 2 33 3 2 4 5//买到4.5就给2元 题解:这道题是很经典的模型题,在这里给出两个方法. 方法一 把每个询问看成一个点,然后A的询问连源点,B的询问连汇点,如果AB间的某个询问有矛盾就在它们中间连一条无限大的边,ans=sum-最小割. // 方法一 把每个询问看成一个点,然后A的询问连源点,B的询问连汇