Description

In China, there are two companies offering the Internet service for the people from all cities: China Telecom and China Unicom. They both are planning to build cables between cities. Obviously, the government wants to connect all the cities in minimum costs. So the minister of finance Mr. B wants to choose some of the
cable plans from the two companies and calculate the minimum cost needed to connect all the cities. Mr. B knows that N-1 cables should be built in order to connect all N cities of China. For some honorable reason, Mr. B should choose K cables from the China Telecom and the rest N-1-K cables from the China Unicom. Your job is to help Mr. B determine which cables should be built and the minimum cost to build them. You may assume that the solution always exists.

Input

Each test case starts with a line containing the number of cities N (1 <= N <= 50,000), number of cable plans M (N-1 <= M <= 100,000) and the number of required
cables from China Telecom K (0 <= K <= N-1). This is followed by M lines, each containing four integers a, b, c, x (0 <= a, b <= N-1, a != b, 1 <= c <= 100, x in {0,1} indicating the pair of cities this cable will connect, the cost to build this cable and the company this cable plan belongs to. x=0 denotes that the cable plan belongs to China Telecom and x=1 denotes that the cable plan is from China Unicom.

Output

For each test case, display the case number and the minimum cost of the cable building.

Sample Input

2 2 1
0 1 1 1
0 1 2 0
2 2 0
0 1 1 1
0 1 2 0

Sample Output

Case 1: 2
Case 2: 1

Hint

In the first case, there are two cable plans between the only two cities, one from China Telecom and one from
China Unicom. Mr. B needs to choose the one from China Telecom to satisfy the problem requirement even the cost is higher.
In the second case, Mr. B must choose the cable from China Unicom, which leads the answer to 1.

题目分析

这个题目在最小生成树的基础上加了一个限制,那就是其中某一种道路必须有k条,先设想一下暴力法如何解题(我认为暴力法最能体现一个题目的解题思路,优化是为了代替暴力法中的某几个高耗时过程),我们需要找到含有k个电信道路的树中的最小生成树,那么为了找到这个最小生成树,我们需要枚举所有的,含有k个电信的道路树,以此来找到含有k个电信道路中的最小生成树。

那么我们给这个最小生成树中 为电信的道路加上任意权值(对这些道路构建费用的改变),这样就得到了另外一组测试样例(只有道路花费不一样),对于这组新的测试样例,求其在含有k个电信的道路情况下的最小生成树,这个最小生成树一定和没有加权值的最小生成树一样(这里的最小生成树是在含有k个电信道路的情况下的最小生成树)。

对于这个东西的证明,因为我们在没有加上权值的情况下已经把所有含有k个电信的道路的树全部枚举出来了,那么设想在这些树中对某一些道路增加一样的构建费用,其结果当然是在没有加权值的情况下的最小生成树的消耗小(这里的最小生成树是在含有k个电信道路的情况的最小生成树)。

好了,以上就是暴力的解题思路,那么我们要如何优化这个暴力法呢?一般人对于没有加上 含有k个电信的情况下 求最小生成树应该很清楚,那么我们就通过找没有这个限制条件下的最小生成树来得到答案。

由以上证明的那个理论我们知道,对于加上了权值的测试数据和没有加上权值的测试数据,在同样含有k个电信道路的情况下的树中,二者这些树中的最小生成树是一样的。那么,如果加上了权值的道路在没有 “必须含有k个电信道路” 这一条件下得到了最小生成树,这个最小生成树的道路中恰好含有k个电信道路,那么这个最小生成树就是我们需要的答案(再次强调,这里的最小生成树是在含有k个电信道路的情况下的最小生成树)

具体来说,我们通过给所有的电信道路加上某一个权值得到一组新的测试数据,对于这组测试数据,我们抛弃“含有k个电信道路”这一条件得到最小生成树,如果这个最小生成树中含有k个电信道路,那么这个最小生成树的道路结构(也就是树的结构)就是在没有加这个权值的情况下在含有k个电信道路的树中是最优的结构,也是答案需要的树的结构。

对于这个题目,不知道是不是我的翻译有问题,这个题目的要求应该是至少含有k个电信道路吧,但是我将刚好为k作为标准得到的结果是错的,而把至少含有k的电信道路作为标准是对的,如果有问题,望指正,谢谢。

代码区

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<sstream>
#include <iterator>
using namespace std;
#define sf(a) scanf_s("%d",&a)
#define sff(a,b) scanf_s("%d%d",&a,&b)
#define sfff(a,b,c) scanf_s("%d%d%d",&a,&b,&c)
#define sffff(a,b,c,d) scanf_s("%d%d%d%d",&a,&b,&c,&d)
#define slf(a) scanf_s("%lld",&a)
#define ssf(str) scanf_s("%s",str)
#define scf(ch) scanf_s("%c",&ch)
#define mem(s,data) memset(s,data,sizeof(s))
#define inf 0x3f3f3f3f
const int max2 = + ;
const int max3 = + ;
const int max4 = + ;
const int max5 = + ;
typedef long long ll; typedef struct Edge{
int s;
int e;
int v;
Edge(int s = , int e = , int v = ) :s(s), e(e), v(v) {};
bool operator<(const Edge& s)const
{
return this->v < s.v;
}
}Edge; Edge e0[max5], e1[max5]; //分别代表x = 0 , x = 1 的道路
int set[max5]; //代表对应下标的城市的父节点
int n, m, k;
void init(int n);
int build(int a, int len0, int len1,int& sum); int main()
{
int kCase = ;
while(sfff(n,m,k)!=EOF)
{
int s, e, v, ok;
int len0=, len1=; //分别记录x = 0 ,x = 1 的道路的个数
for(int i = ;i < m ; i++)
{
sffff(s, e, v, ok);
if (ok)
e1[len1++] = Edge(s, e, v);
else
e0[len0++] = Edge(s, e, v);
}
sort(e0, e0 + len0);
sort(e1, e1 + len1);
int lSide = -;
int rSide = ; int ans = ;
while(lSide <= rSide)
{
const int mid = (lSide + rSide) >> ;
int sum;
const int order = build(mid, len0, len1, sum);
/*if (order == 0)
{
ans = sum - mid * k;
break;
}*/
if (order >= ) //权值太小,或者刚刚好
lSide = mid + , ans = sum - mid * k;
else //权值太大
rSide = mid - ; }
printf("Case %d: %d\n", ++kCase, ans);
}
return ;
} //初始化父节点,也不知道这个题目怎么想的,居然0也表示城市
void init(int n)
{
for (int i = ; i < n; i++)
set[i] = i;
} //找到对应城市的根结点
int find(int x)
{
if (set[x] == x)
return x;
return set[x] = find(set[x]);
} //给电信的每一条道路加上权值a后寻找没有“必须含有k条电信道路”这一限制条件的最小生成树,
//0表示其中含有k个电信道路,1表示权值太小,导致含有电信道路数过多,0表示权值太大
int build(const int a,const int len0,int len1,int& sum)
{
init(n);
sum = ; //初始化
int index0 = , index1 = ; //分别记录了e0,e1的当前最便宜道路
int ans = ; //记录使用了多少个e0的道路
for(int i = ; i < m ; i++)
{
Edge temp;
int flag = ; //记录要构建的是何种道路
if(index0 >= len0 || index1 < len1 && e1[index1].v < e0[index0].v + a) temp = e1[index1++],flag = ;
else temp = e0[index0++];
int s = find(temp.s);
int e = find(temp.e);
if (s != e)
{
set[s] = e;
sum += temp.v;
if (!flag) //电信的道路有额外的权值
sum += a,ans++;
}
}
if (ans == k)return ;
if (ans > k)return ;
return -;
}

HDU 4253-Two Famous Companies(二分+最小生成树)的更多相关文章

  1. HDU 4253 Two Famous Companies

    Two Famous Companies Time Limit: 15000ms Memory Limit: 32768KB This problem will be judged on HDU. O ...

  2. hdu 4253 Two Famous Companies BZOJ 2654 tree

    [题意]:给出n个点,m条边,边分为两种,一种是A公司的,一种是B公司的.边上有权值,问用n-1条边把n个点连起来的最小费用是多少,其中A公司的边刚好有k条.题目保证有解. 思路:我们发现,如果我们给 ...

  3. HDOJ 4253 Two Famous Companies 二分+MST

    题目意思:给出n个点,m条边,边分为两种,一种是A公司的,一种是B公司的.边上有权值, 问用n-1条边把n个点连起来的最小费用是多少,其中A公司的边刚好有k条.题目保证有解. 题解:题目意思很简单就是 ...

  4. hdu4253 Two Famous Companies --- 二分+MST

    给n个点.m条边的图.每条边要么属于a公司,要么属于b公司.要求一颗最小生成树,条件是当中属于a公司的边数为k. 这题做法非常巧妙. 要求最小生成树,但有一定限制,搜索.贪心显然都不正确. 要是能找到 ...

  5. hdu 3433 A Task Process 二分+dp

    A Task Process Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  6. HDU 3622 Bomb Game(二分+2-SAT)

    Bomb Game Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  7. [国家集训队2012]tree(陈立杰) 题解(二分+最小生成树)

    tree 时间限制: 3 Sec  内存限制: 512 MB 题目描述 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. 输入 第一行V, ...

  8. SPOJ COMPANYS Two Famous Companies 最小生成树,二分,思路 难度:2

    http://www.spoj.com/problems/COMPANYS/en/ 题目要求恰好有k条0类边的最小生成树 每次给0类边的权值加或减某个值delta,直到最小生成树上恰好有k条边为0,此 ...

  9. hdu 4253(经典题目:二分+最小生成树)

    题意:就是说有A.B两个公司要修路,有m条路,可能是属于A修的,也可能是属于B修的,现在要求所有路都联通的情况下的最小权值,并且A公司必须要修k条路. 同: 代码: #include<iostr ...

随机推荐

  1. easyUI datagrid中checkbox选中事件以及行点击事件,翻页之后还可以选中

    DataGrid其中与选择,勾选相关 DataGrid属性:singleSelect boolean 如果为true,则只允许选择一行. false ctrlSelect boolean 在启用多行选 ...

  2. TensorFlow使用记录 (十): Pretraining

    上一篇的模型保存和恢复熟练后,我们就可以大量使用 pretrain model 来训练任务了 Tweaking, Dropping, or Replacing the Upper Layers The ...

  3. vfprintf()函数

    函数声明:int vfprintf(FILE *stream, const char *format, va_list arg) 函数参数: stream—这是指向了FILE对象的指针,该FILE对象 ...

  4. 两列布局实现各自独立滚屏,类似与 scrollNav 的功能。

    现在移动端 web 开发越来越靠近 app 的功能.所以两列布局各自都能实现独立滚动也常见.基于固定侧边栏导航,另一侧实现内容展示. 这个功能的核心在于使用 vh 单位. 其中 CSS 的代码是核心点 ...

  5. (70)一篇文章带你熟悉 TCP/IP 协议

    作者:涤生_Woo链接:http://www.jianshu.com/p/9f3e879a4c9c來源:简书著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 同样的,本文篇幅也比较 ...

  6. 微信小程序_(组件)icon、text、rich-text、progress四大基础组件

    微信小程序基础组件官方文档 传送门 Learn 一.icon图标组件 二.rich-text富文本组件 三.text文本组件 四.progress进度条组件 一.icon图标组件 type:icon的 ...

  7. 2016 Multi-University Training Contest 4 部分题解

    1001,官方题解是直接dp,首先dp[i]表示到i位置的种类数,它首先应该等于dp[i-1],(假设m是B串的长度)同时,如果(i-m+1)这个位置开始到i这个位置的这一串是和B串相同的,那么dp[ ...

  8. Javascript引擎的单线程机制和setTimeout执行原理阐述

    工作中使用setTimeout解决了一个问题,于是对setTimeout的相关资料整理了下,以及对js引擎执行的原理一并整理了下,希望能给码农们一些帮助.若发现有错的地方大家及时指出,共同学习进步. ...

  9. navicat for mysql安装

    搜索一款navicat for mysql然后进行下载. 步骤阅读 2 当我们下载完成之后首先进行数据包的解压,同时可以运行navicat for mysql程序. 破解工具下载:https://pa ...

  10. 构建 JVM(HotSpot) 源码调试环境(OpenJDK8)

    原本想在 Windows 下编译调试,但过程中遇到了诸多错误(老是报路径错误...),最后只好放弃. 此次记录调试的方法为 CentOS7 上编译,Windows 上使用 Clion 远程调试(也可直 ...