【问题描述】

很久很久以前有一个国家,这个国家有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. Java应用基础微专业-进阶篇

    第1章--使用对象 1.1 字符类型 char c = 65; // char --> int char c = '\u0041'; // \u: unicode + (Hex 41--> ...

  2. TW实习日记:第28天

    同前两天一样,等接口,开发,调试接口.重复地做着低级代码得搬运工作,确实挺没意思的.怪不得有些人一直说写低级代码很无聊,没有创造性和成就感.31号准备溜了,还是好好复习准备秋招吧. 挖坑清单: Vue ...

  3. hello word!------为什么开通博客以及自我介绍

    来北京已经一年半的日子了,已经完全成功熟练的成为了另一个我,没有了半年前刚来时的那种焦虑.急躁和格格不入. 回想起来那段时间,大概是我人生中非常重要的时期了,去年那个夏天,只身一人背上行囊踏上了北上的 ...

  4. leetcode9_C++判断一个整数是否是回文数

    判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 输出: true 示例 2: 输入: - 输出: false 解释: 从左向右读, 为 - ...

  5. 【未完】训练赛20190304:KMP+树状数组+线段树+优先队列

    头炸了啊,只做出L题,前两天刚看的Shawn zhou的博客学习的,幸亏看了啊,否则就爆零了,发现题目都是经典题,线段树,KMP,我都没看过,最近又在复习考研,真后悔大一大二没好好学习啊,得抽时间好好 ...

  6. Ext JS 6学习文档-第5章-表格组件(grid)

    Ext JS 6学习文档-第5章-表格组件(grid) 使用 Grid 本章将探索 Ext JS 的高级组件 grid .还将使用它帮助读者建立一个功能齐全的公司目录.本章介绍下列几点主题: 基本的 ...

  7. 你真的了解JAVA里的String么

    Java中String类细节问题 (考察点Java内存分配问题) 1. String str1 = "abc";   System.out.println(str1 == &quo ...

  8. 文件操作---基于python

    # coding:utf-8from time import sleepimport sysreload(sys)sys.setdefaultencoding("utf8")f=o ...

  9. 王者荣耀交流协会beta冲刺贡献分分配结果

    根据原来约定的(贡献分分配规则){http://www.cnblogs.com/gaoyb348/p/7828523.html} 总共20个任务,一共35分,那么一个任务1.75分. 冉华完成了9个任 ...

  10. 查看OpenWrt的RAM和FLASH

    加入了博客园,这是第一篇博文,不多写了,从以前博客搬东西过来吧. 买来一个OpenWrt的路由器,今天刚到的货,赶快拆开看看是不是替我换了RAM和FLASH的.那么怎么查看它是不是真的有那么大呢? 在 ...