[BZOJ 2654]tree(陈立杰)

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

V<=50000,E<=100000,所有数据边权为[1,100]中的正整数。

题解

二分+$kruskal$

如果直接$kruskal$求最小生成树,是无法保证白边数量的,那么我们考虑如果改变白边的数量。我们可以把白边全部都加上一个权值,也就是我们二分的值,然后跑最小生成树,同时记录白边数量。当白边数量>=$need$时,$l=mid+1$,否则$r=mid−1$,更新答案就是这棵生成树的权值和减去所有白边的增量。

证明:
我们发现,如果我们给白边增加权值,做最小生成树,由于白边权值增大,导致不容易选白边。记$f(x)$为给白边增加$x$($x$可为负)权值,做最小生成树后,选白边的数量。可以发现,$f(x)$随$x$增大而减小,显然可以二分。
其次,我们发现,由于黑边的权值是不变的,与白边权值不相互影响。同样由于白边之间关系相对不变,必然选出的$need$条白边一定是符合题意的。

 1 #include<map>
 2 #include<ctime>
 3 #include<cmath>
 4 #include<queue>
 5 #include<stack>
 6 #include<cstdio>
 7 #include<string>
 8 #include<vector>
 9 #include<cstring>
10 #include<cstdlib>
11 #include<iostream>
12 #include<algorithm>
13 #define LL long long
14 #define RE register
15 #define IL inline
16 using namespace std;
17 const int V=50000;
18 const int E=100000;
19 
20 int mid;
21 int v,e,need,ans,cnt,tmp;
22 struct tt
23 {
24     int u,v,c,col;
25 }edge[E+5];
26 
27 IL int Kruskal();
28 bool comp(const tt &a,const tt &b) {return a.c+(a.col^1)*mid<b.c+(b.col^1)*mid;}
29 
30 int set[V+5];
31 IL int find(int r) {return set[r]!=-1 ? set[r]=find(set[r]):r;}
32 
33 int main()
34 {
35     scanf("%d%d%d",&v,&e,&need);
36     for  (RE int i=1;i<=e;i++) scanf("%d%d%d%d",&edge[i].u,&edge[i].v,&edge[i].c,&edge[i].col);
37     int l=-100,r=100;
38     while (l<=r)
39     {
40         mid=(l+r)>>1;
41         if (Kruskal()>=need) l=mid+1,ans=tmp;
42         else r=mid-1;
43     }
44     printf("%d\n",ans);
45     return 0;
46 }
47 
48 IL int Kruskal()
49 {
50     tmp=cnt=0;
51     int k=0;
52     memset(set,-1,sizeof(set));
53     sort(edge+1,edge+1+e,comp);
54     for (RE int i=1;i<=e;i++)
55     {
56         int q=find(edge[i].u);
57         int p=find(edge[i].v);
58         if (p!=q)
59         {
60             k+=edge[i].col^1;
61             set[q]=p;
62             cnt++;
63             tmp+=edge[i].c;
64             if (cnt==v-1) break;
65         }
66     }
67     return k;
68 }
BZOJ能过的解法

感谢Hzoi_Maple

由于$COGS$数据会有不满足恰好$need$条白边的情况

打个比方有这样的数据:加$0$时大于$need$,加$1$就小于$need$了。

这样应该在跑最小生成树的时候把所有的白边都加上加的那个权值,结果就是最小生成树的权值和减去$need*$加上的权值,多出来的那一部分完全可以当做黑边来看,因为数据是$100000$的,这样就可以了。(来自Hzoi_Maple

排序的时候,如果边权相同,要把白边放在前面。

要计算当前至多能取多少白边,当然要把白边放前面。由于保证有解,在$cnt>=need$且$cnt$取最小值的方案下,一定能有黑边把多余的白边代替掉。

 1 #include<map>
 2 #include<ctime>
 3 #include<cmath>
 4 #include<queue>
 5 #include<stack>
 6 #include<cstdio>
 7 #include<string>
 8 #include<vector>
 9 #include<cstring>
10 #include<cstdlib>
11 #include<iostream>
12 #include<algorithm>
13 #define LL long long
14 #define RE register
15 #define IL inline
16 using namespace std;
17 const int V=50000;
18 const int E=100000;
19 
20 int mid;
21 int v,e,need,ans,cnt,tmp;
22 struct tt
23 {
24     int u,v,c,col,rc;
25 }edge[E+5];
26 
27 IL int Kruskal();
28 IL void change();
29 bool comp(const tt &a,const tt &b) {return a.rc==b.rc ? a.col<b.col:a.rc<b.rc;}
30 
31 int set[V+5];
32 IL int find(int r) {return set[r]!=-1 ? set[r]=find(set[r]):r;}
33 
34 int main()
35 {
36     scanf("%d%d%d",&v,&e,&need);
37     for  (RE int i=1;i<=e;i++) scanf("%d%d%d%d",&edge[i].u,&edge[i].v,&edge[i].c,&edge[i].col);
38     int l=-100,r=100;
39     while (l<=r)
40     {
41         mid=(l+r)>>1;
42         if (Kruskal()>=need) l=mid+1,ans=tmp-need*mid;
43         else r=mid-1;
44     }
45     printf("%d\n",ans);
46     return 0;
47 }
48 
49 IL void change()
50 {
51     for (RE int i=1;i<=e;i++) edge[i].rc=edge[i].c+(edge[i].col^1)*mid;
52 }
53 IL int Kruskal()
54 {
55     change();
56     tmp=cnt=0;
57     int k=0;
58     memset(set,-1,sizeof(set));
59     sort(edge+1,edge+1+e,comp);
60     for (RE int i=1;i<=e;i++)
61     {
62         int q=find(edge[i].u);
63         int p=find(edge[i].v);
64         if (p!=q)
65         {
66             k+=edge[i].col^1;
67             set[q]=p;
68             cnt++;
69             tmp+=edge[i].rc;
70             if (cnt==v-1) break;
71         }
72     }
73     return k;
74 }
COGS能过的解法

转载于:https://www.cnblogs.com/NaVi-Awson/p/7252243.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/416291.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DM3软件如何在linux中安装,DM3 文件扩展名: 它是什么以及如何打开它?

DM3 疑难解答频繁的 DM3 打开问题ImageJ 不存在你尝试加载 DM3 文件并收到错误&#xff0c;例如 “%%os%% 无法打开 DM3 文件扩展名”。 通常&#xff0c;%%os%% 中会出现这种情况&#xff0c;因为 ImageJ 未安装在你的电脑上。 你将无法双击以打开 DM3&#xff0c;因为你的操作…

CentOS6.8下安装memcached并设置开机自启动

参考资料&#xff1a;http://www.cnblogs.com/handongyu/p/6419305.html http://coolnull.com/1986.html 一、安装libevent 首先检查系统中是否安装了libevent [rootyeebian ~]# rpm -qa | grep libevent 如果安装了则查看libevent的安装路径&#xff0c;后续安装时需要用到 […

ftp 530 linux,Linux启动ftp服务器530 Permission denied解决方法

重新在虚拟机下安装了linux。现在我想启动linux自带的ftp服务器&#xff1a;#service vsftpd start 。如果想linux启动是自动启动ftp服务器&#xff1a;#chkconfig vsftpd on 。运行putty&#xff0c;以root身份进入&#xff0c;出现了报错 530 Permission denied &…

Shiro身份认证授权原理

shiro在应用程序中的使用是用Subject为入口的&#xff0c; 最终subject委托给真正的管理者ShiroSecurityMannager Realm是Shiro获得身份认证信息和来源信息的地方(所以这里是我们实现的)我们只要继承他的实现类重写方法就好了&#xff0c;AuthorizingRealm 身份认证过程 自定义…

linux进程路由策略,linux路由表,策略路由,路由查找

路由表内核中路由表有2种&#xff1a;l 一个是缓存路由(fib)&#xff0c;是自动学习生成自动管理的&#xff0c;用户没必要去干预&#xff0c;但是内核还是提供了方法让用户可以去清空它。但是用户不能设置它的项&#xff0c;但是可以根据这个缓存更新的原理从外部影响他。l 路…

图形桌面linux触摸,新手看招:用图形桌面访问Linux操作系统

创建用户帐户&#xff1a;adduser login-name (OS:Red Hat)useradd login-name (OS:SuSe)为帐户添加密码&#xff1a;passwd login-name (密码应该包括一个数字&#xff0c;且不能为英文单词)结束登录程序&#xff0c;启动另一登录实例&#xff1a;CtrlD从终端启动图形窗口环境…

Python namedtuple(命名元组)使用实例

Python namedtuple(命名元组)使用实例 #!/usr/bin/python3import collectionsMyTupleClass collections.namedtuple(MyTupleClass,[name, age, job]) obj MyTupleClass("Tomsom",12,Cooker) print(obj.name) print(obj.age) print(obj.job)执行结果&#xff1a; To…

pd怎么卸载linux系统,parallels desktop11怎么卸载?parallels desktop11卸载方法

parallels desktop11是一款功能强大的MAC虚拟机软件&#xff0c;用户通过该软件可在mac系统下运行安装windows或Linux操作系统&#xff0c;不过很多时候用户在安装后&#xff0c;由于后期没有使用虚拟机的需求&#xff0c;故此想要将其删除&#xff0c;但是又不知道如何操作&am…

html5中使页面中元素居中

在div中加入 style"text-align: center;

linux下jdk源码安装,Linux JDK 源码安装

一 环境1.1 操作系统[roothost-xxxsoft]# lsb_release -aLSB Version: :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarchDistributor ID: CentOSDescription: CentOS re…

Python map/reduce

2017-07-31 18:20:59 一、map函数 map()&#xff1a;会根据提供的函数对指定序列做映射。第一个参数 function 以参数序列中的每一个元素调用 function 函数&#xff0c;返回包含每次 function 函数返回值的iterator,即迭代器&#xff0c;使用list函数可以将之转成列表。 map(f…

linux裸机安装nginx,linux环境下安装nginx步骤 - 进击的乌龟 - 博客园

开始前&#xff0c;请确认gcc g开发类库是否装好&#xff0c;默认已经安装。ububtu平台编译环境可以使用以下指令apt- get install build- essentialapt - get install libtoolcentos平台编译环境使用如下指令安装make&#xff1a;yum -y install gcc automake autoconf libtoo…

Effective C++ 条款21

必须返回对象时。别妄想返回其reference 我们上节分析了对象引用传递的优点&#xff0c;如今说明函数返回引用对象带来的种种坏处。 先来一段代码&#xff1a; class Rational{ public:Rational(int numerator0, int denominator1);…… private:int n, d;friendconst Rationa…

html 中 em

◆px像素&#xff08;Pixel&#xff09;&#xff0c;相对长度单位。像素px是相对于显示器屏幕分辨率而言的。 ◆em是相对长度单位&#xff0c;相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置&#xff0c;则相对于浏览器的默认字体尺寸。 因此用px来定…

c语言命名参数,按照C语言的规定,实参和形参的命名不得重复。

按照羊脂玉具有( )光泽。衡量睡眠质量好坏包括入睡快慢,睡眠深浅,睡后能否解乏(精神情况、规定是否影响日常的工作和生活)三个方面。参和“有药吃而无伙食命亦难保”提示健康普及必须遵循的经济性原则。形参治病与调补都需要辩证,其中区别在于用药与药量的不同。命得重咳嗽除了…

雇佣兵

题目链接&#xff1a;http://noi.openjudge.cn/ch0105/37/ 总时间限制: 1000ms内存限制: 65536kB描述雇佣兵的体力最大值为M&#xff0c;初始体力值为0、战斗力为N、拥有X个能量元素。 当雇佣兵的体力值恰好为M时&#xff0c;才可以参加一个为期M天的战斗期&#xff0c;战斗期结…

织梦的if(!defined('DEDEINC')) exit("Request Error!");解析

1if(!defined(DEDEINC)) exit("Request Error!");细细看看你就会发现,这句代码一般都是在 /include 路径下的php文件里边,为什么 dede 路径下的php文件没有呢&#xff1f;因为 include 路径下的文件是 类文件,也就是 方法文件 ,是以后要被 require_once 引入的文件,M…