zoj 3232 It's not Floyd Algorithm(强联通分量,缩点)
/******************************************************************/
以下题解来自互联网:Juny的博客
思路核心:给你的闭包其实就是一个有向图;
方法:
1,对此图进行缩点,对于点数为n(n>1)的强连通分量最少要 n 条边,
对点数为 1 的强连通不需要边,这样计算出边数 m1 ;
2,在缩点后的有向无环图中进行反floyd,如果有边a->b,b->c,a->c那么显然a->c可以去掉,
就这样一直去除这样的边,直到不能再去为止,算出最终边数 m2;
3,m1+m2 即为答案;
这样做速度比较慢,但小草还没想出其他好的办法,希望有大牛指点……
/*****************************************************************/
- #include <iostream>
- #include <cstring>
- #include <cstdio>
- #include <cstdlib>
- using namespace std;
- #define MAXN 20010
- #define MAXM 50010
- struct Edge
- {
- int v, next;
- }edge[MAXM]; //边结点数组
- int first[MAXN], stack[MAXN], DFN[MAXN], Low[MAXN], Belong[MAXM];
- // first[]头结点数组,stack[]为栈,DFN[]为深搜次序数组,
- //Belong[]为每个结点所对应的强连通分量标号数组
- // Low[u]为u结点或者u的子树结点所能追溯到的最早栈中结点的次序号
- int instack[MAXM],num[MAXN]; // instack[]为是否在栈中的标记数组
- int n, m, cnt, scnt, top, tot;
- void init()
- {
- cnt = ;
- scnt = top = tot = ;
- memset(first, -, sizeof(first));
- memset(DFN, , sizeof(DFN));
- memset(num,,sizeof(num));
- }
- void read_graph(int u, int v)
- {
- edge[tot].v = v;
- edge[tot].next = first[u];
- first[u] = tot++;
- }
- void Tarjan(int v)
- {
- int t;
- DFN[v] = Low[v] = ++cnt;
- instack[v] = ;
- stack[top++] = v;
- for(int e = first[v]; e != -; e = edge[e].next)
- {
- int j = edge[e].v;
- if(!DFN[j])
- {
- Tarjan(j);
- if(Low[v] > Low[j]) Low[v] = Low[j];
- }
- else if(instack[j] && DFN[j] < Low[v])
- {
- Low[v] = DFN[j];
- }
- }
- if(DFN[v] == Low[v])
- {
- scnt++;
- do
- {
- t = stack[--top];
- instack[t] = ;
- Belong[t] = scnt; //为缩点做准备的
- num[scnt]++;
- }while(t != v);
- }
- }
- void solve()
- {
- for(int i = ; i <= n; i++)
- if(!DFN[i])
- Tarjan(i);
- }
- int main()
- {
- int i,j,map[][],sum1,ans,map1[][];//map1[][]是缩点后新建的图
- while(scanf("%d",&n)!=EOF)
- {
- init();
- ans=;
- memset(map,,sizeof(map));
- memset(map1,,sizeof(map1));
- for(i=;i<=n;i++)
- {
- for(j=;j<=n;j++)
- {
- scanf("%d",&map[i][j]);
- if(map[i][j]==&&i!=j)
- {
- read_graph(i,j);
- }
- }
- }
- solve();
- sum1=;
- for(i=;i<=scnt;i++)
- {
- if(num[i]>)
- sum1+=num[i];
- }
- for(int ii=;ii<=n;ii++)
- {
- for(int jj=;jj<=n;jj++)
- {
- if(map[ii][jj]&&Belong[ii]!=Belong[jj])
- map1[Belong[ii]][Belong[jj]]=;
- }
- }
- for(int ii=;ii<=scnt;ii++)
- for(int jj=;jj<=scnt;jj++)
- for(int kk=;kk<=scnt;kk++)
- if(map1[ii][jj]&&map1[ii][kk]&&map1[kk][jj])//此处在缩点新建图
- map1[ii][jj]=;
- for(int ii=;ii<=scnt;ii++)
- for(int jj=;jj<=scnt;jj++)
- if(map1[ii][jj])
- ans++;
- printf("%d\n",sum1+ans);
- }
- return ;
- }
zoj 3232 It's not Floyd Algorithm(强联通分量,缩点)的更多相关文章
- 【最小割】【Dinic】【强联通分量缩点】bzoj1797 [Ahoi2009]Mincut 最小割
结论: 满足条件一:当一条边的起点和终点不在 残量网络的 一个强联通分量中.且满流. 满足条件二:当一条边的起点和终点分别在 S 和 T 的强联通分量中.且满流.. 网上题解很多的. #include ...
- 【强联通分量缩点】【最长路】【spfa】CH Round #59 - OrzCC杯NOIP模拟赛day1 队爷的讲学计划
10分算法:对于城市网络为一条单向链的数据, 20分算法:对于n<=20的数据,暴力搜出所有的可能路径. 结合以上可以得到30分. 60分算法:分析题意可得使者会带着去的城市也就是这个城市所在强 ...
- Tarjan求强联通分量+缩点
提到Tarjan算法就不得不提一提Tarjan这位老人家 Robert Tarjan,计算机科学家,以LCA.强连通分量等算法闻名.他拥有丰富的商业工作经验,1985年开始任教于普林斯顿大学.Tarj ...
- 【强联通分量缩点】【Tarjan】bzoj1051 [HAOI2006]受欢迎的牛
就是看是否有一些点,从其他任何点出发都可到达 定理:有向无环图中唯一出度为0的点,一定可以由任何点出发均可达. 所以缩点,若出度为零的点(强联通分量)唯一,则答案为该强联通分量中点的度数. 若不唯一, ...
- TOJ 3365 ZOJ 3232 It's not Floyd Algorithm / 强连通分量
It's not Floyd Algorithm 时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte 描述 When a directed grap ...
- ZOJ 3232 It's not Floyd Algorithm --强连通分量+Floyd
题意:给你一个传递闭包的矩阵,mp[u][v] = 1表示u可以到达v,为0代表不可到达,问你至少需要多少条边组成的传递闭包符合这个矩阵给出的关系 分析:考虑一个强连通分量,如果这个分量有n个节点,那 ...
- 【强联通分量缩点】【最短路】【spfa】bzoj1179 [Apio2009]Atm
缩点后转化成 DAG图上的单源最长路问题.spfa/dp随便. #include<cstdio> #include<queue> #include<algorithm&g ...
- 【强联通分量缩点】【搜索】bzoj2208 [Jsoi2010]连通数
两次dfs缩点,然后n次dfs暴搜. #include<cstdio> #include<vector> #include<cstring> using names ...
- BZOJ 1051 & 强联通分量
题意: 怎么说呢...这种题目有点概括不来....还是到原题面上看好了... SOL: 求出强联通分量然后根据分量重构图,如果只有一个点没有出边那么就输出这个点中点的数目. 对就是这样. 哦还有论边双 ...
随机推荐
- HDU 5024 Wang Xifeng's Little Plot(枚举)
题意:求一个图中只有一个90°拐点的路的最大长度. 分析:枚举每一个为'.'的点,求出以该点为拐点的八种路中的最大长度,再比较所有点,得出最大长度即可. 如上样例,这样是个90°的角... 注意:最多 ...
- [windows phone开发]新生助手的开发过程与体会三
由于网络原因,新生助手开发介绍的博客近期一直没有更新,请大家见谅.今天向大家介绍一下新生助手中动态磁帖的实现. 在PhoneApplicationPage中添加如下引用 xmlns:toolkit=& ...
- 搭建eclipse环境下 Nutch+Mysql 二次开发环境
最近看了下Nutch,目前Nutch最新版本2.3.1,支持Hbase.MongoDB等存储,但在搭建和测试过程中发现对Mysql 的支持好像有点问题. 后来将Nutch版本改为2.2.1.基于Nut ...
- 解析php时间戳与日期的转换
php中时间戳与日期的转换. 实现功能:获取某个日期的时间戳,或获取某个时间的PHP时间戳. strtotime能将任何英文文本的日期时间描述解析为Unix时间戳,我们结合mktime()或date( ...
- nginx配置:支持phpfastcgi,nginx和php-cgi通信,部分nginx常量解释
支持phpfastcgi的配置如下: server { listen 8000; server_name localhost; root F:/home/projects/test; i ...
- Demo学习: Basic jQuery
UniGUI是一套基于ExtJS的Delphi的WEB框架,它是使用ExtPascal来转化到ExtJS,ExtJS是一个跨浏览器的JavaScript库,因此UniGUI发布出来的程序可以在各种浏览 ...
- 【转】 申请对齐某种结构体大小的buffer
在大多数情况下,编译器和C库透明地帮你处理对齐问题.POSIX 标明了通过malloc( ), calloc( ), 和 realloc( ) 返回的地址对于任何的C类型来说都是对齐的.在Linux中 ...
- java之classpath到底是什么
如果你输入一个命令,比如java那么系统是如何找到这个命令的呢?按照顺序,系统先在当前目录搜索是否有java.exe, java.bat 等. 如果没有,就得到系统的PATH(不区分大小写)里面查找. ...
- SQLserver中的xp_cmdshell
shell是用户与操作系统对话的一个接口,通过shell告诉操作系统让系统执行我们的指令 xp_cmdshell在sqlserver中默认是关闭的存在安全隐患. --打开xp_cmdshell ;;R ...
- 在Linux下写一个简单的驱动程序
本文首先描述了一个可以实际测试运行的驱动实例,然后由此去讨论Linux下驱动模板的要素,以及Linux上应用程序到驱动的执行过程.相信这样由浅入深.由具体实例到抽象理论的描述更容易初学者入手Linux ...