【问题描述】

很久很久以前有一个国家,这个国家有N个城市,城市由1,2,3,…,N标号,城市间有M条双向道路,每条道路都有两个属性g和s,两个城市间可能有多条道路,并且可能存在将某一城市与其自身连接起来的道路。后来由于战争的原因,国王不得不下令减小花费从而关闭一些道路,但是必须要保证任意两个城市相互可达。

道路花费的计算公式为wG*max{所有剩下道路的属性g}+wS*max{所有剩下道路的属性s},其中wG和wS是给定的值。国王想要在满足连通性的前提下使这个花费最小,现在需要你计算出这个花费。

【输入格式】

输入文件名为road.in。

第一行包含两个正整数N和M。第二行包含两个正整数wG和wS。

后面的M行每行描述一条道路,包含四个正整数u,v,g,s,分别表示道路连接的两个城市以及道路的两个属性。

【输出格式】

输出文件名为road.out。

输出一个整数,表示最小花费。若无论如何不能满足连通性,输出-1。

【输入输出样例】

road.in

3 3 
2 1 
1 2 10 15 
1 2 4 20 
1 3 5 1

road.out

30

【数据规模与约定】

对于10%的数据,N≤10,M≤20;对于30%的数据,N≤100,M≤1000;对于50%的数据,N≤200,M≤5000;

对于100%的数据,N≤400,M≤50000,wG,wS,g,s≤1000000000。

分析:最小生成树问题,只不过有两个量对答案有影响.这种题不可能同时考虑两个量,要消除一个量的影响,就先按照g的大小排序.由于g是排好序的,从小到大枚举边,然后求最小生成树,这就是主要的思路.

这个算法的瓶颈就在于每次插入一条边都要对所有的边排序做最小生成树,非常耗时间.因为有很多边经常被用到,我们可以在处理的时候把它们维护成有序的,这个时候只需要考虑s的大小就可以了,因为max{g}的大小是已知的.每次不用排序了,但是在这么多点中做克鲁斯卡尔算法还是比较慢.

如果新加入一条边,那么组成最小生成树的N条边一定是原来最小生成树的N-1条边和这条新加进来的边中取N-1条边.因为没有选到原来的最小生成树的边一定没有最小生成树上的边优,新加进来的这条边由于不知道它s的具体大小,所以可能在最小生成树中,这样维护一个N条边的边集,每次在上面求最小生成树就可以了.

两个因素互相影响的可以先想办法消除其中一个因素的影响,再来考虑另外一个因素的影响.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll; const ll inf = 1ll << ;
ll n, m, wG, wS, fa[], top, tree[], ans = inf; struct node
{
ll u, v, g, s;
}e[]; bool cmp(node a, node b)
{
return a.g < b.g;
} ll find(ll x)
{
if (x == fa[x])
return x;
return fa[x] = find(fa[x]);
} int main()
{
scanf("%lld%lld", &n, &m);
scanf("%lld%lld", &wG, &wS);
for (int i = ; i <= m; i++)
scanf("%lld%lld%lld%lld", &e[i].u, &e[i].v, &e[i].g, &e[i].s);
sort(e + , e + + m, cmp);
for (int i = ; i <= m; i++)
{
bool flag = false;
for (int j = ; j <= n; j++)
fa[j] = j;
int cur = top + ;
for (int j = ; j <= top; j++)
if (e[tree[j]].s > e[i].s)
{
cur = j;
break;
}
top++;
if (cur == top)
tree[cur] = i;
else
{
for (int j = top; j > cur; j--)
tree[j] = tree[j - ];
tree[cur] = i;
}
int num = ;
for (int j = ; j <= top; j++)
{
int fx = find(e[tree[j]].u), fy = find(e[tree[j]].v);
if (fx != fy)
{
fa[fx] = fy;
tree[++num] = tree[j];
if (tree[j] == i)
flag = ;
}
}
if (num == n - && flag) //如果第i条边的g为最大的g,那么这条边肯定要被选到
ans = min(ans, wG*e[i].g + wS*e[tree[num]].s);
top = num;
}
if (ans == inf)
printf("-1");
else
printf("%lld\n", ans); return ;
}

noip模拟赛 保留道路的更多相关文章

  1. 【NOIP 模拟赛】 道路

    题目描述在二维坐标平面里有 N 个整数点,信息班某一巨佬要访问这 N 个点.刚开始巨佬在点(0,0)处. 每一步,巨佬可以走到上.下.左.右四个点.即假设巨佬当前所在点的坐标是(x,y),那么它下一步 ...

  2. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  3. Nescafe #29 NOIP模拟赛

    Nescafe #29 NOIP模拟赛 不知道这种题发出来算不算侵权...毕竟有的题在$bz$上是权限题,但是在$vijos$似乎又有原题...如果这算是侵权的话请联系我,我会尽快删除,谢谢~ 今天开 ...

  4. NOI.AC NOIP模拟赛 第六场 游记

    NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...

  5. 2016-06-19 NOIP模拟赛

          2016-06-19 NOIP模拟赛 by coolyangzc 共3道题目,时间3小时 题目名 高级打字机 不等数列 经营与开发 源文件 type.cpp/c/pas num.cpp/c ...

  6. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  7. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  8. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  9. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

随机推荐

  1. Spring Cloud(六):Hystrix 监控数据聚合 Turbine【Finchley 版】

    Spring Cloud(六):Hystrix 监控数据聚合 Turbine[Finchley 版]  发表于 2018-04-17 |  更新于 2018-05-07 |  上一篇我们介绍了使用 H ...

  2. Vue-cli 工具 / 通过 Vue-cli 工具重构 todoList

    本博文归纳在 Vue 学习过程中, Vue-cli 工具的使用说明.除此之外还通过 Vue-cli 工具将之前 Vuejs 基本语法当中实现的 todoList 进行重构. 安装 npm instal ...

  3. [堆+贪心]牛客练习赛40-B

    传送门:牛客练习赛40 题面: 小A手头有 n 份任务,他可以以任意顺序完成这些任务,只有完成当前的任务后,他才能做下一个任务 第 i 个任务需要花费  x_i 的时间,同时完成第 i 个任务的时间不 ...

  4. StreamReader和StreamWriter中文乱码问题

    StreamReader和StreamWriter中文乱码问题 1.写入: string  FilePath = @"E:\Measure.csv"; StreamWriter w ...

  5. windows store无法登陆的问题解决方案

    Windows应用商店或商店Apps无法打开或闪退的可选方法 (仅用于10565之前的Windows 10版本) 右键点击任务栏,选择"属性",切换到"导航"选 ...

  6. nordic mesh 任务调度实现

    nordic mesh 任务调度实现 nordic mesh的任务调度室基于定时器实现的,有两个链表结构维护任务. 需要注意的是,任务调度的部分接口只能在"bearer event" ...

  7. opencv打开视频文件出错

    使用C#调用mingw的so文件,在C++端使用opencv打开视频.这样的项目完成过了一个,第二次做的时候,发现opencv打开视频文件出错. 首先怀疑是opencv的opencv_ffmpeg24 ...

  8. Python中package的导入语法

    在Python中,一个目录被称为一个package.import和from语法除了导入module文件之外,还可以导入package,语法如下: # import语法 import dir1.dir2 ...

  9. BluetoothAdapter解析

    这篇文章将会详细解析BluetoothAdapter的详细api, 包括隐藏方法, 每个常量含义. 一 BluetoothAdapter简介 1.继承关系 该类仅继承了Object类; 2.该类作用 ...

  10. ACM hust 2.1

    来自咸鱼王的呻吟 http://www.xiami.com/song/3599639?spm=a1z1s.3521865.23309997.1.PbLu7E 配合咸鱼食用效果更佳(右键新窗口打开) 题 ...