[HDU3072]:Intelligence System(塔尖+贪心)
题目传送门
题目描述
“这一切都是命运石之门的选择。”
试图研制时间机器的机关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(塔尖+贪心)相关推荐
- hdu3072 Intelligence System (最小树形图?)
题意:给一个有向图,问要从0号点能到达所有点所需要经过路径的最小权值和是多少,然而,若两点强联通,则这两点互相到达不需要花费.保证0号点能到达所有点 tarjan缩点以后直接取每个点入边中花费最小的即 ...
- Intelligence System HDU - 3072(强连通分量)
Intelligence System HDU - 3072 题意:一个人要传递命令给所有人,如果两人之间互达,不需任何费用,求最少费用 有向图强连通. 1 #include <bits/std ...
- HDU 3072 SCC Intelligence System
给出一个带权有向图,要使整个图连通.SCC中的点之间花费为0,所以就先缩点,然后缩点后两点之间的权值为最小边的权值,把这些权值累加起来就是答案. 1 #include <iostream> ...
- NOI数据结构:最小树形图
最小树形图-朱刘算法详解 +例题解析 最小树形图-朱刘算法详解 +例题解析_pursuit的博客-CSDN博客_最小树形图 图论 -- 生成树 -- 最小树形图 图论 -- 生成树 -- 最小树形图_ ...
- 【HDOJ图论题集】【转】
1 =============================以下是最小生成树+并查集====================================== 2 [HDU] 3 1213 How ...
- 一系列图论问题[转]
=============================以下是最小生成树+并查集====================================== [HDU] 1213 How Many ...
- 【转载】图论 500题——主要为hdu/poj/zoj
转自--http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...
- 图论复习(各类习题)
可以结合这篇博客进行复习:http://www.cnblogs.com/z360/p/7363034.html 一.强连通分量.缩点 习题: 洛谷--P2746 [USACO5.3]校园网Networ ...
- 图论练习题(存起来练)
=============================以下是最小生成树+并查集====================================== [HDU] 1213 How Man ...
最新文章
- 适合初学者的数据结构_数据结构101:数组-初学者的直观介绍
- 自组织映射网络(SOM)如何解决TSP问题
- 方案类:城中村社区网运营计划书-地方社区发展经典案例
- 【iOS 开发】Objective-C 入门 Xcode 环境详解
- redis cluster配置文件和集群状态详解
- (一)Linux基本知识
- java广度优先爬虫示例,【爬虫】广度优先遍历抓取数据概述
- linux 常用操作指令(随时更新)
- Laravel Collection 常用方法(1)
- hdu 1011 Starship Troopers (树形背包dp)
- oracle如何删除物理表空间,oracle 如何删除被误删物理文件的表空间
- Arcgis Android API开发之离线地图
- Java就业培训教程重点部分的笔记
- 在mac上用文本编辑器写java源代码
- STM32分类及命名规则——学习笔记(1)
- 【请验收】证券开户系统常规版本【SIS-OAS1.52.0】即时验证---验证通过------生产验收报告模板...
- 用canvas画圆饼图
- journalctl命令详解,与如何查看系统日志
- ASP.NET快速入门
- halcon轮廓擦除_Halcon中轮廓分割segment
热门文章
- CODE[VS] 1068 乌龟棋
- Leader AP是什么?带你了解Leader AP的原理及特性
- 阳光可视液晶屏是什么? 阳光可视液晶屏和普通液晶屏的区别
- php 微信小程序虚拟支付,为什么有些小程序可以做虚拟支付
- 线段树(数据结构,递归)
- 抱歉,Xposed真的可以为所欲为——6.你的表白撤不回了
- HTML5第一个项目:HelloWorld!
- 像TransactionScope一样使用DbTransaction
- Web开发必知必会,如何使用 Letsencrypt 为网站签发 HTTPS 证书提供安全支持
- UI非常漂亮的数诚1对1直播/带收徒/带公会/运营版本