【HDU3072】【JZOJ4686】通讯
来源:互联网 发布:苹果5s数据流量开关 编辑:程序博客网 时间:2024/05/02 01:14
Description
“这一切都是命运石之门的选择。”
试图研制时间机器的机关SERN截获了中二科学家伦太郎发往过去的一条短信,并由此得知了伦太郎制作出了电话微波炉(仮)。
为了掌握时间机器的技术,SERN总部必须尽快将这个消息通过地下秘密通讯网络,传达到所有分部。
SERN共有N个部门(总部编号为0),通讯网络有M条单向通讯线路,每条线路有一个固定的通讯花费Ci。
为了保密,消息的传递只能按照固定的方式进行:从一个已知消息的部门向另一个与它有线路的部门传递(可能存在多条通信线路)。我们定义总费用为所有部门传递消息的费用和。
幸运的是,如果两个部门可以直接或间接地相互传递消息(即能按照上述方法将信息由X传递到Y,同时能由Y传递到X),我们就可以忽略它们之间的花费。
由于资金问题(预算都花在粒子对撞机上了),SERN总部的工程师希望知道,达到目标的最小花费是多少。
Solution
这题两个部门之间传递消息如果能免费,那么他们肯定是能互相连通的。
对于整个图,那些是可以互相连通的?我们知道,强连通分量内的元素可以互相到达,那么解决这题的关键,就是找出所有强连通块,这点Tarjan可以解决。
于是,所有在强连通块的边都是没有贡献的。
这时,我们可以将强连通块缩成一个点,于是,原图变成了一个有向无环图。
接下来,我们要选取总边权和最小的边覆盖所有点(也就是找类似树的一个东西)。
由于保证有解,贪心的想,除起点外,每个点选择入边最小的方案是最优的。
Tips:
这里的缩点只是一个含义上的,我们给每个点打上所在强连通块的标记,做完后枚举每条边,如果边连接的两点标记不同,那么这条边在新图中必须存在,那么更新答案即可。
Code
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define fo(i,j,k) for(int i=j;i<=k;i++)#define fd(i,j,k) for(int i=j;i>=k;i--)#define N 50001#define M 100001#define ll long longusing namespace std;int dfn[N],low[N];int dep=0,top=0;int st[N];int to[M],next[M],last[M],val[M],num=0;int c[N],tot=0;bool bz[N];int f[N];void link(int x,int y,int c){ num++; to[num]=y; next[num]=last[x]; last[x]=num; val[num]=c;}void tarjan(int x){ low[x]=dfn[x]=++dep; st[++top]=x; bz[x]=true; for(int i=last[x];i;i=next[i]) { int v=to[i]; if(!dfn[v]) { tarjan(v); low[x]=min(low[x],low[v]); } else if(bz[v]) low[x]=min(low[x],dfn[v]); } if(low[x]==dfn[x]) { tot++; while(st[top+1]!=x && top) { c[st[top]]=tot; bz[st[top]]=false; top--; } }}int main(){ int n,m; scanf("%d %d",&n,&m); while(n && m) { memset(last,0,sizeof(last)); memset(next,0,sizeof(next)); memset(to,0,sizeof(to)); memset(val,0,sizeof(val)); num=0; fo(i,1,m) { int u,v,w; scanf("%d %d %d",&u,&v,&w); link(u,v,w); } memset(bz,0,sizeof(bz)); dep=top=0; tot=0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(c,0,sizeof(c)); memset(st,0,sizeof(st)); tarjan(0); int tt=0; ll ans=0; memset(f,60,sizeof(f)); fo(i,0,n-1) for(int j=last[i];j;j=next[j]) { int v=to[j]; if(c[i]!=c[v]) f[c[v]]=min(f[c[v]],val[j]); } fo(i,1,tot-1) if(i!=c[0]) ans+=f[i]; printf("%lld\n",ans); scanf("%d %d",&n,&m); }}
1 0
- 【HDU3072】【JZOJ4686】通讯
- [JZOJ4686] 通讯 [HDU3072] Intelligence System
- 【JZOJ4686】 通讯
- JZOJ4686. 【NOIP2016提高A组8.12】通讯
- hdu3072
- hdu3072 Intelligence System (Tarjan)
- hdu3072 Intelligence System
- HDU3072 Intelligence System
- hdu3072 Intelligence System
- hdu3072 强联通水题
- hdu3072——Intelligence System
- hdu3072 Intelligence System【强连通】
- 强连通缩点 hdu3072
- HDU3072 Intelligence System【最小树形图】
- JZOJ4686 卡牌游戏 线段树维护贪心策略
- HDU3072 Intelligence System(强连通+最小传递费用+边权)
- hdu3072 Intelligence System(tarjan缩点+最小树形图)
- hdu3072 Intelligence System(Tarjan缩点+最小生成树)
- 事件的三个阶段
- arcengine打开cad文件的几种方法
- Java 如何查询硬盘所有文件
- cordova 文件上传
- 第四章:Linear Models for Classification exercise 1-9
- 【HDU3072】【JZOJ4686】通讯
- opencv学习笔记(一)(VS2015-openCV3.1.0-win10 配置说明)
- 求出任何一维整型数组中的第二大的元素值
- Paint 的一个小知识点
- opencv森林火灾检测-1
- Linux系列之solr单机版环境搭建(五)
- Kafka_2.10-0.10.0.0安装配置文档
- Hrbust 1376 能量项链【区间dp】
- python filter lamda map