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: 求出强联通分量然后根据分量重构图,如果只有一个点没有出边那么就输出这个点中点的数目. 对就是这样. 哦还有论边双 ...
随机推荐
- android ListView_Tiger
xml设计 <?xml version="1.0"?> -<LinearLayout tools:context=".MainActivity" ...
- [Apache Maven Shade Plugin] [example] [001] 官方例子:includes-excludes
链接地址:[Selecting Contents for Uber JAR](http://maven.apache.org/plugins/maven-shade-plugin/examples/i ...
- struts2中访问servlet API
Struts2中的Action没有与任何Servlet API耦合,,但对于WEB应用的控制器而言,不访问Servlet API几乎是不可能的,例如需要跟踪HTTP Session状态等.Struts ...
- C++ Sets
集合(Set)是一种包含已排序对象的关联容器 begin() 返回指向第一个元素的迭代器 clear() 清除所有元素 count() 返回某个值元素的个数 empty() 如果集合为空,返回true ...
- 《怎样实现通过shell脚本将用户踢出系统》
下面是一个将用户踢出系统的脚本: #!/bin/bashread -p "input your username " userps aux | grep "^$user& ...
- module graceful-fs for npm
问题: 今天使用hexo时发现错误,hexo:command not found.于是重新安装hexo.但是在安装好npm后,却发现运行 npm 出现错误,没有找到模块graceful-fs,在纠结了 ...
- Sql 执行删除修改之前添加备份
backyw备份滴数据库名称,w20151124sendmaster 表名称 select * into backyw..w20151124sendmaster from Logistics.E ...
- 利用VSCode进行.Net Core初尝试
1.下载.Net Core,https://www.microsoft.com/net/core#windows,按照页面提示进行SDK的安装. 2.下载VsCode,https://www.visu ...
- OS X EI Capitan安装mcrypt
OS X EI Capitan安装mcrypt (我的博客原文:http://www.jmolboy.com/2015/12/01/mcrypt-extension-on-EI-Capitan/) ...
- win7局域网无法ping通本机的问题解决方法
对于window7系统,很多朋友会发现:默认下是不允许被ping的,其实都系统自带的防护墙所阻止了,新建一个策略就可以实现被ping通,如下操作