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: 求出强联通分量然后根据分量重构图,如果只有一个点没有出边那么就输出这个点中点的数目. 对就是这样. 哦还有论边双 ...
随机推荐
- Linux读写锁的使用
读写锁是用来解决读者写者问题的,读操作可以共享,写操作是排它的,读可以有多个在读,写只有唯一个在写,写的时候不允许读. 具有强读者同步和强写者同步两种形式: 强读者同步:当写者没有进行写操作时,读者就 ...
- devpress控件属性说明表
XtraEditors 库中所有控件的公共功能 全部都可以绑定数据: 全部都可以独立使用或用于由 Developer Express 提供的容器控件(XtraGrid.XtraVerticalGrid ...
- eclipse juno版本中没用 ant
下载了谷歌提供的Android集成开发工具ADT,里面封装了Eclipse,但是很奇怪的是竟然没有Ant插件在里面 标准的Eclipse一般都是内置集成了Ant的. 然后到eclipse的plugin ...
- PHP获取时间日期的多种方法
分享下PHP获取时间日期的多种方法. <?php echo "今天:".date("Y-m-d")."<br>"; ...
- 如何在C#中实现图片缩放
//下面给出三个简单的方法,后面两个方法是扩展,估计有时用得着 //************************************************************// /// ...
- Lua 常用的shell命令
lua作为一种小巧的脚本语言,其函数等动作可以使用shell命令进行运行和调试,以下是几个常用的shell命令.基本格式是 lua [选项参数] [脚本参数] (1)%lua 程序名.lua ...
- Mysql备份--mysqldump&outfile
1.备份工具mysqldump 客户端和服务器端都能用select outfile 只能写到服务器端 2.按表单位备份 a.单个表备份 mysqldump -uusername -p database ...
- Python数据结构——栈、队列的实现(一)
1. 栈 栈(Stack)是限制插入和删除操作只能在一个位置进行的表,该位置是表的末端,称为栈的顶(top).栈的基本操作有PUSH(入栈)和POP(出栈).栈又被称为LIFO(后入先出)表. 1.1 ...
- C# sogou地图API应用总结
地图的初始化1.添加引用地图的API文件: <script src="http://api.go2map.com/maps/js/api_v2.5.1.js" type=&q ...
- Microsoft AzureStorageAccount for Powershell
使用Powershell 创建的存储账户,注意StorageAccountName只能使用小写字母以及数字, -Location参考http://www.cnblogs.com/SignalTips/ ...