题目描述

“这一切都是命运石之门的选择。”

试图研制时间机器的机关SERN截获了中二科学家伦太郎发往过去的一条短 信,并由此得知了伦太郎制作出了电话微波炉(仮)。

为了掌握时间机器的技术,SERN总部必须尽快将这个消息通过地下秘密通讯 网络,传达到所有分部。

SERN共有N个部门(总部编号为0),通讯网络有M条单向通讯线路,每条线 路有一个固定的通讯花费Ci。

为了保密,消息的传递只能按照固定的方式进行:从一个已知消息的部门向 另一个与它有线路的部门传递(可能存在多条通信线路)。我们定义总费用为所 有部门传递消息的费用和。

幸运的是,如果两个部门可以直接或间接地相互传递消息(即能按照上述方 法将信息由X传递到Y,同时能由Y传递到X),我们就可以忽略它们之间的花费。

由于资金问题(预算都花在粒子对撞机上了),SERN总部的工程师希望知道, 达到目标的最小花费是多少。

输入

多组数据,文件以2个0结尾。

每组数据第一行,一个整数N,表示有N个包括总部的部门(从0开始编号)。 然后是一个整数M,表示有M条单向通讯线路。

接下来M行,每行三个整数,Xi,Yi,Ci,表示第i条线路从Xi连向Yi,花费为 Ci。

输出

每组数据一行,一个整数表示达到目标的最小花费。

样例输入

3 3
0 1 100
1 2 50
0 2 100
3 3
0 1 100
1 2 50
2 1 100
2 2
0 1 50
0 1 100
0 0

样例输出

150

100

50

提示

【样例解释】

第一组数据:总部把消息传给分部1,分部1再传给分部2.总费用:100+50=150.

第二组数据:总部把消息传给分部1,由于分部1和分部2可以互相传递消息,所以分部1可以无费用把消息传给2.总费用:100+0=100.

第三组数据:总部把消息传给分部1,最小费用为50.总费用:50.

【数据范围】

对于10%的数据,保证M=N-1

对于另30%的数据,N ≤ 20 ,M ≤ 20

对于100%的数据,N ≤ 50000 ,M ≤ 10^5 ,Ci ≤ 10^5 ,

数据组数 ≤ 5 ,数据保证一定可以将信息传递到所有部门。

考试思路历程

考试的时候就觉得这是道水题,因为很明显的tarjan求强联通分量缩点,然后思路有点乱,想过一个个枚举边然后找min值(这就是正解),但觉得这种做法太傻逼,也就没打,又去看了一遍题面,发现有这么一句话“传达到所有分部”,然后就觉得是要经过所有点,就自然而然的想到了kruscal求最小生成树,但我忽略了最小生成树只是针对于无向图而言的,并不适用于有向图,qj测试点还没输出换行然后就爆零滚粗了。

题解

其实这题确实水,tarjan缩完点后就枚举每一个点然后找权值最小的入边就可以了,只要建个反图就很好处理。

其实是个贪心的思想,至于正确性的话,就是因为题目中保证都能到达,所以找最小入边的正确性也就很显然了,也可以自己话个图理解一下。

最后,对于多测题,数组不清空,爆零两行泪。

收获

还是基础知识不牢固,都不知道kruscal只适用于无向图,以后一定要多注意算法的适用范围这种东西,不然很容易爆零的。

 #include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=5e5+;
int n,m,num,top;
int tot,first[N],nex[N],edge[N],to[N],s[N],in[N],c[N],cnt,low[N],dfn[N];
inline int read(){
int ss=;char bb=getchar();
while(bb<||bb>)bb=getchar();
while(bb>=&&bb<=)ss=(ss<<)+(ss<<)+(bb^),bb=getchar();
return ss;
}
void add(int a,int b,int ci){
to[++tot]=b,edge[tot]=ci,nex[tot]=first[a],first[a]=tot;
}
int totc,firstc[N],toc[N],nexc[N],edgec[N];
void add_c(int a,int b,int ci){
toc[++totc]=b,edgec[totc]=ci,nexc[totc]=firstc[a],firstc[a]=totc;
}
void init(){
tot=;
memset(first,,sizeof(first));
memset(nex,,sizeof(nex));
memset(to,,sizeof(to));
memset(s,,sizeof(s));
memset(in,,sizeof(in));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(c,,sizeof(c));
memset(firstc,,sizeof(firstc));
memset(nexc,,sizeof(nexc));
memset(toc,,sizeof(toc));
memset(edgec,,sizeof(edgec));
top=,totc=,cnt=;
}
void tarjan(int x){
dfn[x]=low[x]=++num;s[++top]=x,in[x]=;
for(int i=first[x];i;i=nex[i]){
int y=to[i];
if(!dfn[y]){
tarjan(y);
low[x]=min(low[y],low[x]);
}
else if(in[y]){
low[x]=min(low[x],dfn[y]);
}
}
if(dfn[x]==low[x]){
cnt++;int y;
do{
y=s[top--],in[y]=;
c[y]=cnt;
}while(x!=y);
}
}
int main(){
for(;;){
n=read();m=read();
if(n==&&m==) break;
int pf=;
init();
for(int i=;i<=m;i++){
int a,b,ci;
a=read(),b=read(),ci=read();
a++,b++;pf+=ci;
add(a,b,ci);
}
if(m==n-){
printf("%d\n",pf);
continue;
}
for(int i=;i<=n;i++) if(!dfn[i]) tarjan(i);
for(int x=;x<=n;x++){
for(int i=first[x];i;i=nex[i]){
int y=to[i];
if(c[x]==c[y]) continue;
//cout<<c[x]<<" "<<c[y]<<" "<<edge[i]<<endl;
add_c(c[y],c[x],edge[i]);
}
}
//for(int i=1;i<=totc;i++) cout<<toc[i]<<" "<<nexc[i]<<" "<<edgec[i]<<endl;
long long ans=;
for(register int x=;x<=cnt;x++){
int res=1e9+;
for(register int i=firstc[x];i;i=nexc[i]){
//cout<<toc[i]<<" ";
//cout<<edgec[i]<<endl;
res=min(res,edgec[i]);
}
ans+=res;
}ans-=(1e9+);
printf("%lld\n",ans);
}
return ;
}

20190716NOIP模拟赛T2 通讯(tarjan缩点+贪心)的更多相关文章

  1. 模拟赛T2 交换 解题报告

    模拟赛T2 交换 解题报告 题目大意: 给定一个序列和若干个区间,每次从区间中选择两个数修改使字典序最小. \(n,m\) 同阶 \(10^6\) 2.1 算法 1 按照题意模拟,枚举交换位置并比较. ...

  2. 通讯(tarjan缩点)(20190716NOIP模拟测试4)

    B. 通讯   题目类型:传统 评测方式:文本比较  内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目描述 “这一切都是命运石之门的选择.” 试图研制时间机器的机关SERN截获了 ...

  3. 20181029NOIP模拟赛T2

    2.追捕 [题目背景] Duan2baka:“jmsyzsfq天下第一蠢!” jmsyzsfq:“你说什么?!” [题目描述] 于是Duan2baka开始了逃亡的旅程,而jmsyzsfq也开始追捕Du ...

  4. 【2019.8.14 慈溪模拟赛 T2】黑心老板(gamble)(2-SAT)

    \(2-SAT\) 考虑每个点只能选择\(R\)或\(B\),可以看作选\(0\)或\(1\). 然后对于给出的关系式,若其中一个位置满足关系式,另两个位置就必须不满足关系式,这样就可以对于每个关系式 ...

  5. 【洛谷P5008 逛庭院】tarjan缩点+贪心

    既然没有题解,那么我就来提供给一份. -- 首先我们看到数据范围.妈耶!数据这么大,一开始还想用个DP来做,但是看着就不行,那么根据这个数据范围,我们大致可以猜到这道题的算法是一个贪心,那么我们怎么贪 ...

  6. 模拟赛T2 线段树优化建图+tarjan+拓扑排序

    然而这只是 70pts 的部分分,考场上没想到满分怎么做(现在也不会) code: #include <cstdio> #include <string> #include & ...

  7. 20161003 NOIP 模拟赛 T2 解题报告

    Weed duyege的电脑上面已经长草了,经过辨认上面有金坷垃的痕迹. 为了查出真相,duyege 准备修好电脑之后再进行一次金坷垃的模拟实验. 电脑上面有若干层金坷垃,每次只能在上面撒上一层高度为 ...

  8. NOIP欢乐模拟赛 T2 解题报告

    小澳的坐标系 (coordinate.cpp/c/pas) [题目描述] 小澳者表也,数学者景也,表动则景随矣. 小澳不喜欢数学,可数学却待小澳如初恋,小澳睡觉的时候也不放过. 小澳的梦境中出现了一个 ...

  9. 20180530模拟赛T2——绀碧之棺

    题目背景 qiancl 得到了一张藏宝图,上面写了一道谜题. 题目描述 定义\(F(n)\)为 n 在十进制下各个数位的平方和,求区间\([a,b]\)中有多少\(n\)满足\(k\times F(n ...

随机推荐

  1. Java8排序

    @Data @AllArgsConstructor @NoArgsConstructor public class Apple { private int wight; } 排序 List<In ...

  2. 关于jar冲突的解决方向servlet-api

    1.可以考虑尽量往  java自带的jar  靠  比如说jdk-tools 2.如果用springboot项目  让其他jar 排除servlet-api的依赖 <dependency> ...

  3. HTML5之fileReader异步读取文件及文件切片读取

    fileReader的方法与事件 fileReade实现图片预加载 fileReade实现文件读取进度条 fileReade的与file.s实现文件切片读取 一.fileReader的方法与事件 1. ...

  4. java enum类自定义属性

    enum类自定义属性 这就是enum比static静态变量好用的地方了,可以赋予每一个枚举值若干个属性,例如 实例1: public enum GasStationChannel { ZH(" ...

  5. vue项目使用qrcodejs2生成二维码

    最近写项目遇到一个需求,根据后台给的地址生成二维码,在网上找了下,qrcodejs2使用还是比较多,试了下也能实现需求,就整理下使用方法,方便以后使用   1. 安装包 cnpm i qrcodejs ...

  6. Hadoop入门到实战全套大数据Hadoop学习视频

    资料获取方式,关注公总号RaoRao1994,查看往期精彩-所有文章或者后台回复[Hadoop]获取,即可获取资源下载链接 更多资源获取,请关注公总号RaoRao1994

  7. python:常用模块 知识整理

    time模块 time.time() # 时间戳:1487130156.419527 time.strftime("%Y-%m-%d %X") #格式化的时间字符串:'2017-0 ...

  8. 第十一章· MHA高可用及读写分离

    一.MHA简介 1.1.作者简介 松信嘉範: MySQL/Linux专家 2001年索尼公司入职 2001年开始使用oracle 2004年开始使用MySQL 2006年9月-2010年8月MySQL ...

  9. MySQL连表查询练习题

    1.建库 库名:linux50 字符集:utf8 校验规则:utf8_general_ci  create database linux4 charset utf8 default collate ...

  10. Jmeter中间件处理-缓存

    前言 消息队列和缓存是目前主流的中间件,我们在日常测试过程中,无论是接口还是压力测试,都会遇到需要处理这些中间件数据的情况.本文以Redis对缓存做一个简单的介绍,并基于Jmeter实现缓存数据处理. ...