[图论]强联通分量+缩点 Summer Holiday
Summer Holiday
Description
听说lcy帮大家预定了新马泰7日游,Wiskey真是高兴的夜不能寐啊,他想着得快点把这消息告诉大家,虽然他手上有所有人的联系方式,但是一个一个联系过去实在太耗时间和电话费了。他知道其他人也有一些别人的联系方式,这样他可以通知其他人,再让其他人帮忙通知一下别人。你能帮Wiskey计算出至少要通知多少人,至少得花多少电话费就能让所有人都被通知到吗?
Input
多组测试数组,以EOF结束。
第一行两个整数N和M(1<=N<=1000, 1<=M<=2000),表示人数和联系对数。
接下一行有N个整数,表示Wiskey联系第i个人的电话费用。
接着有M行,每行有两个整数X,Y,表示X能联系到Y,但是不表示Y也能联系X。
output
输出最小联系人数和最小花费。
每个CASE输出答案一行。
Examples
Input
12 16 2 2 2 2 2 2 2 2 2 2 2 2 1 3 3 2 2 1 3 4 2 4 3 5 5 4 4 6 6 4 7 4 7 12 7 8 8 7 8 9 10 9 11 10
Output
3 6
正确解法:
若它是一个无向图,则可以用并查集来解决,可是这是一个有向图。
就用强联通分量来写,先判断他们的强联通分量。然后看每个点的下点是否和自己属于同一块,若不属于同一块,标记一下入度=1,也就是说我们只要考虑入度为0的强联通分量即可,至于入度为1的强联通分量,会有入度为0的点传到那边,就不用考虑了。
我们再来看入度为0的强联通分量中代价最小的那一个,我们就让他来传话。
最小联系人数就是入度为0的强联通分量的个数,最小花费就是 个数*各自代价最小
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <queue> 7 #include <vector> 8 #include <set> 9 #include <map> 10 #include <stack> 11 typedef long long ll; 12 const int N=1000+100; 13 const int mod=1e9+7; 14 const int inf=0x7fffffff; 15 using namespace std; 16 int n,m,Bcnt=0,a[N]; 17 int Link[N],len=0,id=0; 18 int tin[N],low[N],bok[N],indu[N],mincost[N]; 19 int belong[N]; 20 stack<int>s; 21 struct node 22 { 23 int y,next; 24 }e[2010]; 25 void add(int xx,int yy) 26 { 27 e[++len].next=Link[xx]; 28 Link[xx]=len; 29 e[len].y=yy; 30 } 31 void tarjan(int u) 32 { 33 tin[u]=low[u]=++id; 34 s.push(u); 35 bok[u]=1; 36 for(int i=Link[u];i;i=e[i].next) 37 { 38 int v=e[i].y; 39 if(!tin[v]) 40 { 41 tarjan(v); 42 low[u]=min(low[u],low[v]); 43 } 44 else if(bok[v]) 45 { 46 low[u]=min(low[u],tin[v]); 47 } 48 } 49 if(tin[u]==low[u]) 50 { 51 Bcnt++; 52 while(true) 53 { 54 int v=s.top(); 55 s.pop(); 56 bok[v]=0; 57 belong[v]=Bcnt; 58 if(u==v) break; 59 } 60 } 61 } 62 int main() 63 { 64 while(scanf("%d %d",&n,&m)!=EOF) 65 { 66 if(n==0) break; 67 memset(bok,0,sizeof(bok)); 68 memset(Link,0,sizeof(Link)); 69 memset(e,0,sizeof(e)); 70 memset(tin,0,sizeof(tin)); 71 memset(low,0,sizeof(low)); 72 memset(belong,0,sizeof(belong)); 73 memset(a,0,sizeof(a)); 74 memset(indu,0,sizeof(indu)); 75 Bcnt=0; id=0; len=0; 76 int xx,yy; 77 for(int i=1;i<=n;i++) 78 scanf("%d",&a[i]); 79 while(m--) 80 { 81 scanf("%d %d",&xx,&yy); 82 add(xx,yy); 83 } 84 for(int i=1;i<=n;i++) 85 if(!tin[i]) 86 tarjan(i); 87 for(int i=1;i<=n;i++) 88 for(int j=Link[i];j;j=e[j].next) 89 { 90 int kkk=e[j].y; 91 if(belong[i]!=belong[kkk]) 92 indu[belong[kkk]]=1; 93 } 94 for(int i=1;i<=Bcnt;i++) 95 mincost[i]=999999999; 96 for(int i=1;i<=n;i++) 97 if(mincost[belong[i]]>a[i]&&indu[belong[i]]==0) 98 mincost[belong[i]]=a[i]; 99 int ans=0,sum=0; 100 for(int i=1;i<=Bcnt;i++) 101 { 102 if(indu[i]!=0) continue; 103 ans++; 104 sum+=mincost[i]; 105 } 106 printf("%d %d\n",ans,sum); 107 //printf("hello\n"); 108 } 109 110 return 0; 111 }
View Code
转载于:https://www.cnblogs.com/Kaike/p/11144019.html
[图论]强联通分量+缩点 Summer Holiday相关推荐
- P3387-【模板】缩点【tarjan,强联通分量,DAGdp】
正题 评测记录: https://www.luogu.org/recordnew/lists?uid=52918&pid=P3387 大意 一个有向图.每个点有权值,但每个值只能取一次,每条边 ...
- 强联通分量与双连通分量
强联通分量 1.概念 在有向图G中,如果两点互相可达,则称这两个点强连通,如果G中任意两点互相可达,则称G是强连通图. 定理: 1.一个有向图是强连通的,当且仅当G中有一个回路,它至少包含每个节点一次 ...
- CodeForces 1213F (强联通分量分解+拓扑排序)
传送门 •题意 给你两个数组 p,q ,分别存放 1~n 的某个全排列: 让你根据这两个数组构造一个字符串 S,要求: (1)$\forall i \in [1,n-1],S_{pi}\leq S _ ...
- Tarjan的强联通分量
求强联通分量有很多种. <C++信息学奥赛一本通> 中讲过一个dfs求强联通分量的算法Kosdaraju,为了骗字数我就待会简单的说说.然而我们这篇文章的主体是Tarjan,所以我肯定说 ...
- POJ 3694Network(Tarjan边双联通分量 + 缩点 + LCA并查集维护)
[题意]: 有N个结点M条边的图,有Q次操作,每次操作在点x, y之间加一条边,加完E(x, y)后还有几个桥(割边),每次操作会累积,影响下一次操作. [思路]: 先用Tarjan求出一开始总的桥的 ...
- 关于强联通分量 的求法讨论
这个讨论主要是关于 HA2006年最受欢迎的牛 的讨论 . 尽管这道题对于很多dalao来说都觉得是模板题,但是仍是值得思考的,因为我第一次写这道题的时候, 缩完点之后建图建错玄学跑dfs n^2做法 ...
- POJ 2186 Popular Cows (强联通分量)
链接 :http://poj.org/problem?id=2186 一个联通分量里的所有的牛满足任何一个被其他牛认为是红人.强联通缩点之后 只需要找到一个且只有一个联通分量且它的出度为0 答案就是这 ...
- [vios1023]维多利亚的舞会3强联通分量tarjan
题目链接:https://vijos.org/p/1023 最近在练强联通分量,当然学的是tarjan算法 而这一道题虽然打着难度为3,且是tarjan算法的裸题出没在vijos里面 但其实并不是纯粹 ...
- BZOJ 2140 稳定婚姻(强联通分量判环)【BZOJ修复工程】
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2140 是 hydro 的 BZOJ ...
最新文章
- linux软件安装不完全傻瓜手册
- 统计1000个10以内随机数随机数出现的个数
- 【LeetCode】LeetCode之删除并获得点数——动态规划、排序+动态规划
- 运行startup.bat的启动过程
- linux python 信号,Python模块之信号(signal)
- Python判断变量类型
- 图像处理之卷积---任意卷积核的快速实现
- HTML5的新特性(1) -pattern
- ExtJs4 基础必备
- 原生js动态添加元素
- VMware 10M网卡变1000M兆网卡
- python3 import的一个细节
- 显示构造函数模式 — Revealing Constructor Pattern
- prisma中where对象转换RedisJson查询字符串
- vue datepicker 动态控制时分秒 当前时间以后可选
- es+ik+kibana的简单使用
- 棋盘覆盖问题C++版
- Kali Linux中无法使用pip的解决方法
- 下单账号与支付账号不一致,请核实后再支付 问题原因
- 从Google Maglev到UCloud Vortex,如何造一个牛逼的负载均衡?