刷题总结——保留道路(ssoj)
题目:
题目背景
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
备注
【数据规模与约定】
对于 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)的更多相关文章
- 刷题总结——探险(ssoj)
题目: 国家探险队长 Jack 意外弄到了一份秦始皇的藏宝图,于是,探险队一行人便踏上寻宝之旅,去寻找传说中的宝藏. 藏宝点分布在森林的各处,每个点有一个值,表示藏宝的价值.它们之间由一些小路相连,小 ...
- 刷题总结——xor(ssoj)
题目: 题目背景 OURCE:NOIP2015-SHY-7 题目描述 求一棵带边权的树的一条最大 Xor 路径的值.这里的“路径”不一定从根到叶子结点,中间一段路径只要满足条件也可以. 输入格式 第一 ...
- 刷题总结——array(ssoj)
题目: 题目描述 给定 2 个正整数序列 A1, A2,序列长度分别为 L1, L2.你可以进行以下的一次操作:1. 选择两个数 K1,K2(1≤K1≤L1, 1≤K2≤L2):2. 移去 A1 中最 ...
- 刷题总结——蜥蜴(ssoj网络流)
题目: 题目背景 SCOI2007 DAY1 T3 题目描述 在一个 r 行 c 列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外.每行每列中相邻石柱的距 ...
- 刷题总结——选课(ssoj树形dp+记忆化搜索+多叉树转二叉树)
题目: 题目描述 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了 N(N<300)门的选修课程,每个学生可选课程的数量 M 是给定的.学生选修了这M门课 ...
- 刷题总结——字符串(ssoj)
题目: 给定n个小的字符串T和一个大的字符串S,先输出T总共再S中出现了多少次 然后q个询问···每次修改S上的一个字母,然后再次输出上述答案··· n小于1000,q<200000,T的总长度 ...
- 刷题总结——run(ssoj)
题目: 题目描述 企鹅国正在举办全面运动会,第一项比赛就是跑步.N 个人在圆形跑道上跑步,他们都有各自的速度和起点.但这个跑步规则很奇怪,当两个人相遇的时候编号较小的就会出局,当场上剩下最后一个人的时 ...
- 刷题总结——work(ssoj)
题目: 题目背景 SOURCE:NOIP2015-SHY-5 题目描述 假设现在离 noip 还有 m 天,有 n 个人要去参加比赛.他们每个人都有一个预定的训练量 r[i] ,所以每一天他们都抓紧时 ...
- 刷题总结——ball(ssoj)
题目: 题目背景 SOURCE:NOIP2015-SHY-9 题目描述 Alice 与 Bob 在玩游戏.他们一共玩了 t 轮游戏.游戏中,他们分别获得了 n 个和 m 个小球.每个球上有一个分数.每 ...
随机推荐
- 从binlog恢复数据及Mysqlbinlog文件删除
做了mysql主从也有一段时间了,这两天检查磁盘空间情况,发现放数据库的分区磁盘激增了40多G,一路查看下来,发现配置好主从复制以来到现在的binlog就有40多G,原来根源出在这里,查看了一下my. ...
- Javafinal变量
class Test02 { public static void main(String args[]){ final int x; x = 100; // ...
- 洛谷P1628 合并序列
题目描述 有N个单词和字符串T,按字典序输出以字符串T为前缀的所有单词. 输入输出格式 输入格式: 输入文件第一行包含一个正整数N: 接下来N行,每行一个单词,长度不超过100: 最后一行包含字符串T ...
- [转]八款开源Android游戏引擎
八款开源Android游戏引擎 1.Angle Angle是一款专为Android平台设计的,敏捷且适合快速开发的2D游戏引擎,基于OpenGL ES技术开发.该引擎全部用Java代码编写,并且可以根 ...
- 高精度A+B
#include<stdio.h> #include<string.h> int main() { int lenth1,lenth2,n,i,j,k,s; scanf(&qu ...
- map最基本操作
#include<iostream> #include<map> using namespace std; int main() { /*map<int,char> ...
- 利用python进行数据分析1_numpy的基本操作,建模基础
import numpy as np # 生成指定维度的随机多维数据 data=np.random.rand(2,3) print(data) print(type(data)) 结果: [[0.11 ...
- Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'userController' method
在使用SpringMVC的时候遇到了这个问题 问题原因: 在指定方法所对应的url地址的时候重复了, 也就是@RequestMapping("url")中, 两个方法使用了同一个 ...
- Java InputStream、String、File相互转化
String --> InputStreamByteArrayInputStream stream = new ByteArrayInputStream(str.getBytes()); Inp ...
- ECMAScript5 [].reduce()
ECMAScript 5 的2个归并数组的方法,reduce() reduceRight() 两个方法都会迭代数组的所有项,然后构建一个最终返回的值. 两个参数: 1.函数,一个在每一项上调用的函 ...