题目:

题目背景

161114-练习-DAY1-AHSDFZ T3

题目描述

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

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

输入格式

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

输出格式

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

样例数据 1

输入  [复制]

 

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

输出

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

题解:

30 分做法:
按照 g 属性从小到大排序,枚举 maxG,对满足 maxG 的所有道路
按照 s 属性从小到大排序,然后做 kruskal,时间复杂度O(M^2logM)。

50 分做法:
在 30 分基础上,发现每次只增加一条边,插入到上次的边集合中再做 kruskal 即可,时间复杂度 O(M^2)。

100 分做法:
依旧按照 g 属性从小到大排序。丌断加入新边的过程中发现,当前的最小生成树只可能是由未加入新边的最小生成树的边和当前新边组成的共 N 条边中选出 N-1 条构成。因此维护一个最小生成树边集,每次只在 N 条边中做最小生成树,时间复杂度 O(MN)。

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cctype>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int N=;
struct node
{
int go;
int to;
int g;
int s;
}ed[N];
int n,m,fa[];
int sta[],tot,num;
long long wG,wS;
long long ans=2e18+;
inline int Ri()
{
char c;
int i=,f=;
for(c=getchar();(c>''||c<'')&&c!='-';c=getchar());
if(c=='-')
{
i=-;
c=getchar();
}
for(;c<=''&&c>='';c=getchar())
f=(f+(f<<)<<)+(c^'');
return f*i;
}
inline long long Rl()
{
char c;
long long i=,f=;
for(c=getchar();(c>''||c<'')&&c!='-';c=getchar());
if(c=='-')
{
i=-;
c=getchar();
}
for(;c<=''&&c>='';c=getchar())
f=(f+(f<<)<<)+(c^'');
return f*i;
}
inline int getfa(int x)
{
if(fa[x]==x) return x;
else return getfa(fa[x]);
}
inline void comb(int x,int y)
{
int Fx=getfa(x);
int Fy=getfa(y);
if(Fx!=Fy)
fa[Fx]=Fy;
}
bool comp(node a,node b)
{
if(a.g==b.g) return a.s<b.s;
return a.g<b.g;
}
int main()
{
//freopen("a.in","r",stdin);
n=Ri();
m=Ri();
wG=Rl();
wS=Rl();
for(int i=;i<=m;i++)
{
ed[i].go=Ri();
ed[i].to=Ri();
ed[i].g=Ri();
ed[i].s=Ri();
}
sort(ed+,ed+m+,comp);
tot=;
int j;
for(int i=;i<=m;i++)
{
for(j=;j<=n;j++)
fa[j]=j;
for(j=tot;j>=;j--)
{
if(ed[sta[j]].s>ed[i].s)
sta[j+]=sta[j];
else
break;
}
tot++,sta[j+]=i;
num=;
for(j=;j<=tot;j++)
{
int Fg=getfa(ed[sta[j]].go);
int Ft=getfa(ed[sta[j]].to);
if(Fg!=Ft)
{
fa[Fg]=Ft;
sta[++num]=sta[j];
}
}
if(num==n-)
ans=min(ans,ed[sta[num]].s*wS+ed[i].g*wG);
tot=num;
}
if(ans==2e18+) cout<<"-1"<<endl;
else cout<<ans<<endl;
return ;
}

刷题总结——保留道路(ssoj)的更多相关文章

  1. 刷题总结——探险(ssoj)

    题目: 国家探险队长 Jack 意外弄到了一份秦始皇的藏宝图,于是,探险队一行人便踏上寻宝之旅,去寻找传说中的宝藏. 藏宝点分布在森林的各处,每个点有一个值,表示藏宝的价值.它们之间由一些小路相连,小 ...

  2. 刷题总结——xor(ssoj)

    题目: 题目背景 OURCE:NOIP2015-SHY-7 题目描述 求一棵带边权的树的一条最大 Xor 路径的值.这里的“路径”不一定从根到叶子结点,中间一段路径只要满足条件也可以. 输入格式 第一 ...

  3. 刷题总结——array(ssoj)

    题目: 题目描述 给定 2 个正整数序列 A1, A2,序列长度分别为 L1, L2.你可以进行以下的一次操作:1. 选择两个数 K1,K2(1≤K1≤L1, 1≤K2≤L2):2. 移去 A1 中最 ...

  4. 刷题总结——蜥蜴(ssoj网络流)

    题目: 题目背景 SCOI2007 DAY1 T3 题目描述 在一个 r 行 c 列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外.每行每列中相邻石柱的距 ...

  5. 刷题总结——选课(ssoj树形dp+记忆化搜索+多叉树转二叉树)

    题目: 题目描述 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了 N(N<300)门的选修课程,每个学生可选课程的数量 M 是给定的.学生选修了这M门课 ...

  6. 刷题总结——字符串(ssoj)

    题目: 给定n个小的字符串T和一个大的字符串S,先输出T总共再S中出现了多少次 然后q个询问···每次修改S上的一个字母,然后再次输出上述答案··· n小于1000,q<200000,T的总长度 ...

  7. 刷题总结——run(ssoj)

    题目: 题目描述 企鹅国正在举办全面运动会,第一项比赛就是跑步.N 个人在圆形跑道上跑步,他们都有各自的速度和起点.但这个跑步规则很奇怪,当两个人相遇的时候编号较小的就会出局,当场上剩下最后一个人的时 ...

  8. 刷题总结——work(ssoj)

    题目: 题目背景 SOURCE:NOIP2015-SHY-5 题目描述 假设现在离 noip 还有 m 天,有 n 个人要去参加比赛.他们每个人都有一个预定的训练量 r[i] ,所以每一天他们都抓紧时 ...

  9. 刷题总结——ball(ssoj)

    题目: 题目背景 SOURCE:NOIP2015-SHY-9 题目描述 Alice 与 Bob 在玩游戏.他们一共玩了 t 轮游戏.游戏中,他们分别获得了 n 个和 m 个小球.每个球上有一个分数.每 ...

随机推荐

  1. 关于软件测试(5):初识Peer Review

    一.背景:这周的软件测试课堂上我们在自行分组的情况下,对姚同学的汽车停车位定位管理系统进行了Peer Review,中文就是同行测试.这也是我第一次接触同行测试,那接下来我先介绍一下Peer Revi ...

  2. MFC技术积累——基于MFC对话框类的那些事儿

    1. 创建对话框类 (1)打开VC++6.0环境,点击:文件→新建: (2)在弹出的新建对话框中选择:工程→MFC AppWizard (exe)→输入工程名称(例如:功能调试)→工程保存路径名→确定 ...

  3. Docker镜像的目录存储讲解

    我们成功安装完docker后,执行命令行sudo docker run hello-world, 如果是第一次执行,则会从远程拉取hello-world的镜像到本地,然后运行,显示hello worl ...

  4. 网络大牛如何回答Chrome的15个刁钻面试题?

    (内容来自网络整理) Google的面试题在刁钻古怪方面相当出名,甚至已经有些被神化的味道.这里整理出15道Google面试题并一一给出了网络大牛的答案,其中不少都是流传很广的. 第1题:让你清洗西雅 ...

  5. 简单明了理解Java移位运算符

    无须多言: @Test public void intro() { assertThat("应该相等", -1 >> 1, equalTo(-1)); assertTh ...

  6. jQuery中ready方法的实现

    https://blog.csdn.net/major_zhang/article/details/80146674 先普及一下jquery.ready()和window.onload,window. ...

  7. Open Cascade:AIS_InteractiveContext如何调用函数选择AIS对象

    AIS_InteractiveContext如何调用函数选择AIS对象 myAISContext->MoveTo(point.x, point.y, myView); myAISContext- ...

  8. 二分查找 && 三分查找

    LeetCode34. Find First and Last Position of Element in Sorted Array 题意:找出指定元素出现的范围,Ologn 思路:两次二分 cla ...

  9. xampp中php手动升级

    http://windows.php.net/download/           //要下载的 里面有dll文件 http://www.php.net/downloads.php VC9 x86 ...

  10. CentOS 7 升级gcc/g++编译器

    gcc的升级必须要使用源码进行升级,也就说,必须要使用源码进行编译才行.我的7.2的CentOS目前自带的gcc是4.8.5的,gcc从4.8之后开始支持C++11,但是鉴于现在C++14.C++17 ...