题目传送门


题目描述

“这一切都是命运石之门的选择。”
试图研制时间机器的机关SERN截获了中二科学家伦太郎发往过去的一条短 信,并由此得知了伦太郎制作出了电话微波炉(仮)。
为了掌握时间机器的技术,SERN总部必须尽快将这个消息通过地下秘密通讯 网络,传达到所有分部。
SERN共有N个部门(总部编号为0),通讯网络有M条单向通讯线路,每条线 路有一个固定的通讯花费$C_i$。
为了保密,消息的传递只能按照固定的方式进行:从一个已知消息的部门向 另一个与它有线路的部门传递(可能存在多条通信线路)。我们定义总费用为所 有部门传递消息的费用和。
幸运的是,如果两个部门可以直接或间接地相互传递消息(即能按照上述方法将信息由X传递到Y,同时能由Y传递到X),我们就可以忽略它们之间的花费。
由于资金问题(预算都花在粒子对撞机上了),SERN总部的工程师希望知道, 达到目标的最小花费是多少。


输入格式

多组数据,文件以2个0结尾。
每组数据第一行,一个整数N,表示有N个包括总部的部门(从0开始编号)。 然后是一个整数M,表示有M条单向通讯线路。
接下来M行,每行三个整数$X_i$,$Y_i$,$C_i$,表示第i条线路从$X_i$连向$Y_i$,花费为$C_i$。


输出格式

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


样例

样例输入:

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≤105,$C_i$≤105,数据组数≤5。
数据保证一定可以将信息传递到所有部门。


题解

不知道你有没有注意到这句话:

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

这意味着什么呢?

就是说,在一个强联通分量里,任意两点之间相互到达的花费为0,那么直接一个塔尖缩点刚上去就好了。

那么缩完点之后要怎么计算答案呢?

考虑这样一个问题,贪心思想,我们要从根节点到达所有点,每一个点被到达一次即可,那么我们就找所有能到达这个点中权值最小的那个边,走它就好了。

枚举所有的边,找非强联通分量里的边,不断更新这条边的to的最小值即可。

模板一定要打对!!!


代码时刻

本题代码:

#include<bits/stdc++.h>
using namespace std;
struct rec
{int nxt;int to;int w;
}e[100010];//存边
int n,m;
int head[50010],cnt;
int dfn[50010],low[50010],sta[50010],ins[50010],c[50010],num,top,tot;//塔尖
int ans;//存储答案
int fl[50010];//存储最小的那个边
void pre_work()//多测不清空,爆零两行泪TAT……
{cnt=num=top=tot=0;ans=0;for(int i=1;i<=n;i++)head[i]=dfn[i]=low[i]=ins[i]=c[i]=0;memset(fl,0x3f,sizeof(fl));
}
void add(int x,int y,int w)//建边
{e[++cnt].nxt=head[x];e[cnt].to=y;e[cnt].w=w;head[x]=cnt;
}
void tarjan(int x)//塔尖求强联通分量
{dfn[x]=low[x]=++num;sta[++top]=x;ins[x]=1;for(int i=head[x];i;i=e[i].nxt){if(!dfn[e[i].to]){tarjan(e[i].to);low[x]=min(low[x],low[e[i].to]);}else if(ins[e[i].to])low[x]=min(low[x],dfn[e[i].to]);}if(dfn[x]==low[x]){tot++;int y;do{y=sta[top--];ins[y]=0;c[y]=tot;}while(x!=y);}
}
int main()
{memset(fl,0x3f,sizeof(fl));while(1){scanf("%d%d",&n,&m);if(!n&&!m)break;for(int i=1;i<=m;i++){int x,y,c;scanf("%d%d%d",&x,&y,&c);add(x+1,y+1,c);}tarjan(1);for(int x=1;x<=n;x++)for(int i=head[x];i;i=e[i].nxt)if(c[x]!=c[e[i].to])fl[c[e[i].to]]=min(fl[c[e[i].to]],e[i].w);//不断更新最小值fl[c[1]]=0;for(int i=1;i<=tot;i++)ans+=fl[i];printf("%d\n",ans);pre_work();}return 0;
}

HDU代码(输入格式不同):

#include<bits/stdc++.h>
using namespace std;
struct rec
{int nxt;int to;int w;
}e[100010];
int n,m;
int head[50010],cnt;
int dfn[50010],low[50010],sta[50010],ins[50010],c[50010],num,top,tot;
int ans;
int fl[50010];
void pre_work()
{cnt=num=top=tot=0;ans=0;for(int i=1;i<=n;i++)head[i]=dfn[i]=low[i]=ins[i]=c[i]=0;memset(fl,0x3f,sizeof(fl));
}
void add(int x,int y,int w)
{e[++cnt].nxt=head[x];e[cnt].to=y;e[cnt].w=w;head[x]=cnt;
}
void tarjan(int x)
{dfn[x]=low[x]=++num;sta[++top]=x;ins[x]=1;for(int i=head[x];i;i=e[i].nxt){if(!dfn[e[i].to]){tarjan(e[i].to);low[x]=min(low[x],low[e[i].to]);}else if(ins[e[i].to])low[x]=min(low[x],dfn[e[i].to]);}if(dfn[x]==low[x]){tot++;int y;do{y=sta[top--];ins[y]=0;c[y]=tot;}while(x!=y);}
}
int main()
{memset(fl,0x3f,sizeof(fl));while(~scanf("%d%d",&n,&m)){for(int i=1;i<=m;i++){int x,y,c;scanf("%d%d%d",&x,&y,&c);add(x+1,y+1,c);}tarjan(1);for(int x=1;x<=n;x++)for(int i=head[x];i;i=e[i].nxt)if(c[x]!=c[e[i].to])fl[c[e[i].to]]=min(fl[c[e[i].to]],e[i].w);fl[c[1]]=0;for(int i=1;i<=tot;i++)ans+=fl[i];printf("%d\n",ans);pre_work();}return 0;
}


rp++

转载于:https://www.cnblogs.com/wzc521/p/11196134.html

[HDU3072]:Intelligence System(塔尖+贪心)相关推荐

  1. hdu3072 Intelligence System (最小树形图?)

    题意:给一个有向图,问要从0号点能到达所有点所需要经过路径的最小权值和是多少,然而,若两点强联通,则这两点互相到达不需要花费.保证0号点能到达所有点 tarjan缩点以后直接取每个点入边中花费最小的即 ...

  2. Intelligence System HDU - 3072(强连通分量)

    Intelligence System HDU - 3072 题意:一个人要传递命令给所有人,如果两人之间互达,不需任何费用,求最少费用 有向图强连通. 1 #include <bits/std ...

  3. HDU 3072 SCC Intelligence System

    给出一个带权有向图,要使整个图连通.SCC中的点之间花费为0,所以就先缩点,然后缩点后两点之间的权值为最小边的权值,把这些权值累加起来就是答案. 1 #include <iostream> ...

  4. NOI数据结构:最小树形图

    最小树形图-朱刘算法详解 +例题解析 最小树形图-朱刘算法详解 +例题解析_pursuit的博客-CSDN博客_最小树形图 图论 -- 生成树 -- 最小树形图 图论 -- 生成树 -- 最小树形图_ ...

  5. 【HDOJ图论题集】【转】

    1 =============================以下是最小生成树+并查集====================================== 2 [HDU] 3 1213 How ...

  6. 一系列图论问题[转]

    =============================以下是最小生成树+并查集====================================== [HDU] 1213 How Many ...

  7. 【转载】图论 500题——主要为hdu/poj/zoj

    转自--http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...

  8. 图论复习(各类习题)

    可以结合这篇博客进行复习:http://www.cnblogs.com/z360/p/7363034.html 一.强连通分量.缩点 习题: 洛谷--P2746 [USACO5.3]校园网Networ ...

  9. 图论练习题(存起来练)

    =============================以下是最小生成树+并查集======================================  [HDU]  1213 How Man ...

最新文章

  1. 适合初学者的数据结构_数据结构101:数组-初学者的直观介绍
  2. 自组织映射网络(SOM)如何解决TSP问题
  3. 方案类:城中村社区网运营计划书-地方社区发展经典案例
  4. 【iOS 开发】Objective-C 入门 Xcode 环境详解
  5. redis cluster配置文件和集群状态详解
  6. (一)Linux基本知识
  7. java广度优先爬虫示例,【爬虫】广度优先遍历抓取数据概述
  8. linux 常用操作指令(随时更新)
  9. Laravel Collection 常用方法(1)
  10. hdu 1011 Starship Troopers (树形背包dp)
  11. oracle如何删除物理表空间,oracle 如何删除被误删物理文件的表空间
  12. Arcgis Android API开发之离线地图
  13. Java就业培训教程重点部分的笔记
  14. 在mac上用文本编辑器写java源代码
  15. STM32分类及命名规则——学习笔记(1)
  16. 【请验收】证券开户系统常规版本【SIS-OAS1.52.0】即时验证---验证通过------生产验收报告模板...
  17. 用canvas画圆饼图
  18. journalctl命令详解,与如何查看系统日志
  19. ASP.NET快速入门
  20. halcon轮廓擦除_Halcon中轮廓分割segment

热门文章

  1. CODE[VS] 1068 乌龟棋
  2. Leader AP是什么?带你了解Leader AP的原理及特性
  3. 阳光可视液晶屏是什么? 阳光可视液晶屏和普通液晶屏的区别
  4. php 微信小程序虚拟支付,为什么有些小程序可以做虚拟支付
  5. 线段树(数据结构,递归)
  6. 抱歉,Xposed真的可以为所欲为——6.你的表白撤不回了
  7. HTML5第一个项目:HelloWorld!
  8. 像TransactionScope一样使用DbTransaction
  9. Web开发必知必会,如何使用 Letsencrypt 为网站签发 HTTPS 证书提供安全支持
  10. UI非常漂亮的数诚1对1直播/带收徒/带公会/运营版本