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相关推荐

  1. P3387-【模板】缩点【tarjan,强联通分量,DAGdp】

    正题 评测记录: https://www.luogu.org/recordnew/lists?uid=52918&pid=P3387 大意 一个有向图.每个点有权值,但每个值只能取一次,每条边 ...

  2. 强联通分量与双连通分量

    强联通分量 1.概念 在有向图G中,如果两点互相可达,则称这两个点强连通,如果G中任意两点互相可达,则称G是强连通图. 定理: 1.一个有向图是强连通的,当且仅当G中有一个回路,它至少包含每个节点一次 ...

  3. CodeForces 1213F (强联通分量分解+拓扑排序)

    传送门 •题意 给你两个数组 p,q ,分别存放 1~n 的某个全排列: 让你根据这两个数组构造一个字符串 S,要求: (1)$\forall i \in [1,n-1],S_{pi}\leq S _ ...

  4. Tarjan的强联通分量

    求强联通分量有很多种. <C++信息学奥赛一本通>  中讲过一个dfs求强联通分量的算法Kosdaraju,为了骗字数我就待会简单的说说.然而我们这篇文章的主体是Tarjan,所以我肯定说 ...

  5. POJ 3694Network(Tarjan边双联通分量 + 缩点 + LCA并查集维护)

    [题意]: 有N个结点M条边的图,有Q次操作,每次操作在点x, y之间加一条边,加完E(x, y)后还有几个桥(割边),每次操作会累积,影响下一次操作. [思路]: 先用Tarjan求出一开始总的桥的 ...

  6. 关于强联通分量 的求法讨论

    这个讨论主要是关于 HA2006年最受欢迎的牛 的讨论 . 尽管这道题对于很多dalao来说都觉得是模板题,但是仍是值得思考的,因为我第一次写这道题的时候, 缩完点之后建图建错玄学跑dfs n^2做法 ...

  7. POJ 2186 Popular Cows (强联通分量)

    链接 :http://poj.org/problem?id=2186 一个联通分量里的所有的牛满足任何一个被其他牛认为是红人.强联通缩点之后 只需要找到一个且只有一个联通分量且它的出度为0 答案就是这 ...

  8. [vios1023]维多利亚的舞会3强联通分量tarjan

    题目链接:https://vijos.org/p/1023 最近在练强联通分量,当然学的是tarjan算法 而这一道题虽然打着难度为3,且是tarjan算法的裸题出没在vijos里面 但其实并不是纯粹 ...

  9. BZOJ 2140 稳定婚姻(强联通分量判环)【BZOJ修复工程】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2140 是 hydro 的 BZOJ ...

最新文章

  1. linux软件安装不完全傻瓜手册
  2. 统计1000个10以内随机数随机数出现的个数
  3. 【LeetCode】LeetCode之删除并获得点数——动态规划、排序+动态规划
  4. 运行startup.bat的启动过程
  5. linux python 信号,Python模块之信号(signal)
  6. Python判断变量类型
  7. 图像处理之卷积---任意卷积核的快速实现
  8. HTML5的新特性(1) -pattern
  9. ExtJs4 基础必备
  10. 原生js动态添加元素
  11. VMware 10M网卡变1000M兆网卡
  12. python3 import的一个细节
  13. 显示构造函数模式 — Revealing Constructor Pattern
  14. prisma中where对象转换RedisJson查询字符串
  15. vue datepicker 动态控制时分秒 当前时间以后可选
  16. es+ik+kibana的简单使用
  17. 棋盘覆盖问题C++版
  18. Kali Linux中无法使用pip的解决方法
  19. 下单账号与支付账号不一致,请核实后再支付 问题原因
  20. 从Google Maglev到UCloud Vortex,如何造一个牛逼的负载均衡?

热门文章

  1. 【收藏】比Xshel更好用的 FinalShell
  2. Python配置pip国内镜像源
  3. Spark on YARN cluster client 模式作业运行全过程分析
  4. loadrunner脚本设计:参数化
  5. Linux 光盘的挂载和解挂
  6. Linux shell只读变量
  7. redis设置为控制台打印日志
  8. thymeleaf获取当前时间并格式化输出
  9. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(七)
  10. 详细推导PCA算法(包括算法推导必备的知识)