问题 B: 通讯

时间限制: 1 Sec  内存限制: 256 MB

题面


题目描述

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

试图研制时间机器的机关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强连通分量缩点+最短路。

然后就这么打了。还是没认真读题,花了30分钟码出来tarjan和dijkstra,还问了老师有没有负边权。

结果样例都过不去。心态有点崩。然后柳暗花明,kruskal,跳进了最小生成树的坑里就没起来。

这是有向图欸。我是怎么“天才”地把无向图算法引入到有向图里面的?这个本应贪心100却最小生成树10分的教训我能记一辈子。。

再学图论算法一定要把有向图和无向图看清楚!

题解


膜一发tarjan大神!

因为是有向图,而且题面明显给到了“如果两个部门可以直接或间接地相互传递消息我们就可以忽略它们之间的花费”

这几乎就是强连通分量的标准定义了。tarjan强连通分量缩点板子。

不知道各位大神怎么处理的贪心,我建了个反图然后跑出来每个点入边中的最小值。

因为“数据保证一定可以将信息传递到所有部门”,所以贪心策略正确。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<stack>
#include<algorithm>
#define rint register int
using namespace std;
int n,m,xi,yi,ci,tot,first[],first_f[];
struct node{int u,v,w,nxt;}edge[],edge_q[],edge_f[];
int tot_q,first_q[];
stack <int> s;
int dfn[],low[],cnt,sum,sum1;
bool ins[];
int dist[],fa[];
int belong[],dp[];
bool vis[];
long long ans=;
inline void renew()
{
tot=tot_q=cnt=sum=ans=;
for(rint i=;i<=n;++i)
{first[i]=first_q[i]=dfn[i]=low[i]=belong[i]=first_f[i]=;ins[i]=vis[i]=false;fa[i]=i;}
for(rint i=;i<=m;++i)
edge[i].u=edge[i].v=edge[i].w=edge[i].nxt=,
edge_q[i].u=edge_q[i].v=edge_q[i].w=edge_q[i].nxt=,
edge_f[i].u=edge_f[i].v=edge_f[i].w=edge_f[i].nxt=;
}
inline int get(int x){return x==fa[x]?x:fa[x]=get(fa[x]);}
inline bool cmp(node aa,node bb){return aa.w<bb.w;}
inline void add(int uu,int vv,int ww)
{
++tot;
edge[tot].u=uu;
edge[tot].v=vv;
edge[tot].w=ww;
edge[tot].nxt=first[uu];
first[uu]=tot;
}
inline void add_q(int uu,int vv,int ww)
{
++sum;
edge_q[sum].u=uu;
edge_q[sum].v=vv;
edge_q[sum].w=ww;
edge_q[sum].nxt=first_q[uu];
first_q[uu]=sum;
}
inline void add_f(int uu,int vv,int ww)
{
++sum1;
edge_f[sum1].u=uu;
edge_f[sum1].v=vv;
edge_f[sum1].w=ww;
edge_f[sum1].nxt=first_f[uu];
first_f[uu]=sum1;
}
inline void tarjan(int x)
{
dfn[x]=low[x]=++cnt;
s.push(x);ins[x]=;
for(rint i=first[x];i;i=edge[i].nxt)
{
int y=edge[i].v;
if(!dfn[y])
{
tarjan(y);
low[x]=min(low[x],low[y]);
}
else if(ins[y])
low[x]=min(low[x],dfn[y]);
}
if(dfn[x]==low[x])
{
tot_q++;
while()
{
int l_top=s.top();
s.pop();ins[l_top]=false;
belong[l_top]=tot_q;
if(l_top==x)break;
}
}
return ;
}
int main()
{
while()
{
scanf("%d %d",&n,&m);
if(n==&&m==)return ;
renew();
for(rint i=;i<=m;++i)
{
scanf("%d %d %d",&xi,&yi,&ci);
xi++,yi++;
add(xi,yi,ci);
}
tarjan();
for(rint i=;i<=n;++i)
for(rint j=first[i];j;j=edge[j].nxt)
{
int y=edge[j].v;
if(belong[i]==belong[y])continue;
add_q(belong[i],belong[y],edge[j].w);
add_f(belong[y],belong[i],edge[j].w);
}
for(rint i=;i<=tot_q;++i)
{
if(i==belong[])continue;
int minn=0x7fffffff;
for(rint j=first_f[i];j;j=edge_f[j].nxt)
{
minn=min(edge_f[j].w,minn);
}
ans+=minn;
}
printf("%lld\n",ans);
}
}

「题解」:07.16NOIP模拟T2:通讯的更多相关文章

  1. 「题解」「美团 CodeM 资格赛」跳格子

    目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...

  2. 「题解」「HNOI2013」切糕

    文章目录 「题解」「HNOI2013」切糕 题目描述 思路分析及代码 题目分析 题解及代码 「题解」「HNOI2013」切糕 题目描述 点这里 思路分析及代码 题目分析 这道题的题目可以说得上是史上最 ...

  3. 「题解」JOIOI 王国

    「题解」JOIOI 王国 题目描述 考场思考 正解 题目描述 点这里 考场思考 因为时间不太够了,直接一上来就着手暴力.但是本人太菜,居然暴力爆 000 ,然后当场自闭- 一气之下,发现对 60pts ...

  4. 「题解」:07.16NOIP模拟T1:礼物

    问题 A: 礼物 时间限制: 1 Sec  内存限制: 256 MB 题面 题目描述 夏川的生日就要到了.作为夏川形式上的男朋友,季堂打算给夏川买一些生 日礼物. 商店里一共有种礼物.夏川每得到一种礼 ...

  5. 「题解」:07.18NOIP模拟赛T1:星际旅行

    问题 A: 星际旅行 时间限制: 1 Sec  内存限制: 256 MB 题面 题面谢绝公开. 考试心路历程 拿到这道题感觉很懵逼,所以先搞的T2和T3,最后码了个暴力,结果还不如直接输出‘0’得分高 ...

  6. 「题解」NOIP模拟测试题解乱写II(36)

    毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...

  7. 「题解」NOIP模拟测试题解乱写I(29-31)

    NOIP模拟29(B) T1爬山 简单题,赛时找到了$O(1)$查询的规律于是切了. 从倍增LCA那里借鉴了一点东西:先将a.b抬到同一高度,然后再一起往上爬.所用的步数$×2$就是了. 抬升到同一高 ...

  8. 「题解」「2014 NOI模拟赛 Day7」冒泡排序

    目录 题目 考场思考 正解 题目勾起了我对我蒟蒻时代的回忆,虽然我现在也蒟蒻 题目 点这里 可能链接会挂,在网上搜题目就有. 毕竟 \(BZOJ\) 有点老了... 考场思考 本来以为十分友善的一道题 ...

  9. 「 题解」NOIP2021模拟赛(2021-07-19)

    小兔的话 欢迎大家在评论区留言哦~ D - 矩阵 简单题意 一个 \(i * i\) 的 \(01\) 矩阵,若满足 每一行 和 每一列 都满足 恰好 有 \(2\) 个位置是 \(1\) 时,称为 ...

随机推荐

  1. python爬虫环境1

    转载 https://cuiqingcai.com/5052.html 1.1 python3安装  配置环境变量:随后点击“新建”,新建一个条目,将刚才复制的C:\Python36复制进去.这里需要 ...

  2. ES6(阮一峰)对象的扩展

    1.属性的简洁表示法 允许直接写入变量和函数,作为对象的属性和方法. const foo = 'bar'; const baz = {foo};//等同于 const baz = {foo : &qu ...

  3. Delphi 堆栈 [ heap(堆) 和 stack(栈) ]

    程序需要的内存空间分为 heap(堆) 和 stack(栈); heap(堆) 是自由存储区, stack(栈) 是自动存储区; 使用 heap 需要手动申请.手动释放, 使用 stack 是自动申请 ...

  4. ruby中数组认识

    a = 1...5这样赋值,a不是数组类型,1...5操作是一种枚举类型. a = ["1","2","3","4"], ...

  5. DELPHI常用类型及定义单元

    Controls Application (the variable not a type) Forms Beep SysUtils or Windows (different functions) ...

  6. 127.0.0.1和localhost不能正确映射的问题

    可能引起的问题: 检查:分别ping一下127.0.0.1和localhost 以上是正确演示,不匹配的话,ping localhost会返回: 解决方案: 可能1: 在浏览器中打开http://12 ...

  7. SDOI2017 树点染色

    \[SDOI2017 树点染色\] 题目描述 Bob 有一棵 $ n $ 个点的有根树,其中 $ 1 $ 号点是根节点.Bob 在每个节点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是,这 ...

  8. 行内元素与块级元素的区别,行内块级元素在IE8-的兼容性

    行内元素与块级元素的区别 行内元素最好不要包裹块级元素,但是块级元素可以任意的包裹行内元素 行内元素如果其上一个元素也是行内元素,则他们会分布在统一水平线上,即在一行上排列,块级元素不论上一个元素是行 ...

  9. vscode 编写Python走过的坑

    1,在使用vscode 中import turtle 这个模块, 再调用t = turtle.Pen(),始终提示无法找到turtle模块 2.可是使用terminal 中调用turtle模块,没有问 ...

  10. git回退单个文件

    git原理 Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD. gi ...