当前位置: 首页 > news >正文

poj 1236 scc强连通分量

分析部分摘自:http://www.cnblogs.com/kuangbin/archive/2011/08/07/2130277.html

强连通分量缩点求入度为0的个数和出度为0的分量个数

题目大意:N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输,问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件。2,至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校最终都能得到软件。

 

也就是:

        给定一个有向图,求:

 

1) 至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点

 

2) 至少要加多少条边,才能使得从任何一个顶点出发,都能到达全部顶点

 

        顶点数<= 100

解题思路:

        1. 求出所有强连通分量

        2. 每个强连通分量缩成一点,则形成一个有向无环图DAG

        3. DAG上面有多少个入度为0的顶点,问题1的答案就是多少

在DAG上要加几条边,才能使得DAG变成强连通的,问题2的答案就是多少

加边的方法:

要为每个入度为0的点添加入边,为每个出度为0的点添加出边

假定有 n 个入度为0的点,m个出度为0的点,如何加边?

把所有入度为0的点编号 0,1,2,3,4 ....N -1

每次为一个编号为i的入度0点可达的出度0点,添加一条出边,连到编号为(i+1)%N 的那个出度0点,

这需要加n条边

若 m <= n,则

加了这n条边后,已经没有入度0点,则问题解决,一共加了n条边

若 m > n,则还有m-n个入度0点,则从这些点以外任取一点,和这些点都连上边,即可,这还需加m-n条边。

所以,max(m,n)就是第二个问题的解

此外:当只有一个强连通分支的时候,就是缩点后只有一个点,虽然入度出度为0的都有一个,但是实际上不需要增加清单的项了,所以答案是1,0

Sample Input

5
2 4 3 0
4 5 0
0
0
1 0

Sample Output

1
2

Source

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 const int MAXN=20010;//点数
  5 const int MAXM=50010;//边数
  6 struct Edge
  7 {
  8     int to,next;
  9 }edge[MAXM];
 10 int head[MAXN],tot;
 11 int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];//Belong数组的值是1~scc
 12 int Index,top;
 13 int scc;//强连通分量的个数
 14 bool Instack[MAXN];
 15 int num[MAXN];//各个强连通分量包含点的个数,数组编号1~scc
 16 //num数组不一定需要,结合实际情况
 17 int out[MAXN],tmp,Num,ans,in[MAXN];
 18 void addedge(int u,int v)
 19 {
 20     edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++;
 21 }
 22 void Tarjan(int u)
 23 {
 24     int v;
 25     Low[u]=DFN[u]=++Index;
 26     Stack[top++]=u;
 27     Instack[u]=true;
 28     for(int i=head[u];i != -1;i=edge[i].next)
 29     {
 30         v=edge[i].to;
 31         if(!DFN[v])
 32         {
 33             Tarjan(v);
 34             if(Low[u] > Low[v])Low[u]=Low[v];
 35         }
 36         else if(Instack[v] && Low[u] > DFN[v])
 37         Low[u]=DFN[v];
 38     }
 39     if(Low[u]==DFN[u])
 40     {
 41         scc++;
 42         do
 43         {
 44             v=Stack[--top];
 45             Instack[v]=false;
 46             Belong[v]=scc;
 47             num[scc]++;
 48         }
 49         while(v != u);
 50     }
 51 }
 52 void solve(int N)
 53 {
 54     memset(out,0,sizeof(out));
 55     memset(in,0,sizeof(in));
 56     memset(Belong,0,sizeof(Belong));
 57     memset(DFN,0,sizeof(DFN));
 58     memset(Instack,false,sizeof(Instack));
 59     memset(num,0,sizeof(num));
 60     Index=scc=top=0;
 61     for(int i=1;i <= N;i++)
 62         if(!DFN[i])
 63             Tarjan(i);
 64 }
 65 void init()
 66 {
 67     tot=0;
 68     memset(head,-1,sizeof(head));
 69 }
 70 int main()
 71 {
 72     int n,m;
 73     int i,j,v;
 74     //freopen("1.in","r",stdin);
 75     while(scanf("%d",&n)!=EOF)
 76     {
 77         init();
 78         int q,p;
 79         for(i=1;i<=n;i++)
 80         {
 81             while(scanf("%d",&m)!=EOF)
 82             {
 83                 if(m==0)    break;
 84                 addedge(i,m);
 85             }
 86         }
 87         solve(n);
 88         for(i=1;i<=n;i++)
 89         {
 90             for(v=head[i];v!=-1;v=edge[v].next)
 91             {
 92                 if(Belong[i]!=Belong[edge[v].to])
 93                 {
 94                     out[Belong[i]]++;
 95                     in[Belong[edge[v].to]]++;
 96 
 97                 }
 98             }
 99         }
100         int o0=0,i0=0;
101         //printf("%d\n",scc);
102         for(i=1;i<=scc;i++)
103         {
104             //printf("%d %d\n",out[i],in[i]);
105             if(!out[i]) o0++;
106             if(!in[i])  i0++;
107         }
108         if(scc==1) {printf("1\n0\n");continue;}
109         printf("%d\n",i0);
110         printf("%d\n",i0>o0?i0:o0);
111     }
112     return 0;
113 }

 

转载于:https://www.cnblogs.com/cnblogs321114287/p/4280181.html

相关文章:

  • Javascript模块化编程(一):模块的写法
  • leetcode[44]Wildcard Matching
  • scanf,sscanf利用format跳过干扰的空格
  • 无线路由器之间桥接组网
  • busybox中的tftp使用
  • 庙庙湖
  • AOJ 0009 Prime Number(求素数)
  • PAT 1025 反转链表
  • Android -- 滑式抽屉SlidingDrawer(非原创)
  • 前端不为人知的一面--前端冷知识集锦
  • javascript组件——轮播图
  • hdu 5178 pairs(BC第一题,,方法不止一种,,我用lower_bound那种。。。)
  • eclipse经常卡死
  • 使用视图(带索引)
  • 三边测量法:通过三点坐标和到三点的距离,返回第4点位置
  • bearychat的java client
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • CAP 一致性协议及应用解析
  • Git 使用集
  • golang中接口赋值与方法集
  • isset在php5.6-和php7.0+的一些差异
  • Java,console输出实时的转向GUI textbox
  • java小心机(3)| 浅析finalize()
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • Python利用正则抓取网页内容保存到本地
  • React-redux的原理以及使用
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 实习面试笔记
  • 实现简单的正则表达式引擎
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 微信开放平台全网发布【失败】的几点排查方法
  • 写代码的正确姿势
  • 用Canvas画一棵二叉树
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • ​​​​​​​​​​​​​​Γ函数
  • #考研#计算机文化知识1(局域网及网络互联)
  • (1)SpringCloud 整合Python
  • (MATLAB)第五章-矩阵运算
  • (zt)最盛行的警世狂言(爆笑)
  • (搬运以学习)flask 上下文的实现
  • (差分)胡桃爱原石
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (十七)devops持续集成开发——使用jenkins流水线pipeline方式发布一个微服务项目
  • (十五)devops持续集成开发——jenkins流水线构建策略配置及触发器的使用
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。
  • (转)Linux整合apache和tomcat构建Web服务器
  • .NET开源项目介绍及资源推荐:数据持久层 (微软MVP写作)
  • [ARC066F]Contest with Drinks Hard
  • [Ariticle] 厚黑之道 一 小狐狸听故事
  • [C++]模板与STL简介
  • [Codeforces] number theory (R1600) Part.11
  • [flink总结]什么是flink背压 ,有什么危害? 如何解决flink背压?flink如何保证端到端一致性?