题目

/******************************************************************/

以下题解来自互联网: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(强联通分量,缩点)的更多相关文章

  1. 【最小割】【Dinic】【强联通分量缩点】bzoj1797 [Ahoi2009]Mincut 最小割

    结论: 满足条件一:当一条边的起点和终点不在 残量网络的 一个强联通分量中.且满流. 满足条件二:当一条边的起点和终点分别在 S 和 T 的强联通分量中.且满流.. 网上题解很多的. #include ...

  2. 【强联通分量缩点】【最长路】【spfa】CH Round #59 - OrzCC杯NOIP模拟赛day1 队爷的讲学计划

    10分算法:对于城市网络为一条单向链的数据, 20分算法:对于n<=20的数据,暴力搜出所有的可能路径. 结合以上可以得到30分. 60分算法:分析题意可得使者会带着去的城市也就是这个城市所在强 ...

  3. Tarjan求强联通分量+缩点

    提到Tarjan算法就不得不提一提Tarjan这位老人家 Robert Tarjan,计算机科学家,以LCA.强连通分量等算法闻名.他拥有丰富的商业工作经验,1985年开始任教于普林斯顿大学.Tarj ...

  4. 【强联通分量缩点】【Tarjan】bzoj1051 [HAOI2006]受欢迎的牛

    就是看是否有一些点,从其他任何点出发都可到达 定理:有向无环图中唯一出度为0的点,一定可以由任何点出发均可达. 所以缩点,若出度为零的点(强联通分量)唯一,则答案为该强联通分量中点的度数. 若不唯一, ...

  5. TOJ 3365 ZOJ 3232 It's not Floyd Algorithm / 强连通分量

    It's not Floyd Algorithm 时间限制(普通/Java):1000MS/3000MS     运行内存限制:65536KByte   描述 When a directed grap ...

  6. ZOJ 3232 It's not Floyd Algorithm --强连通分量+Floyd

    题意:给你一个传递闭包的矩阵,mp[u][v] = 1表示u可以到达v,为0代表不可到达,问你至少需要多少条边组成的传递闭包符合这个矩阵给出的关系 分析:考虑一个强连通分量,如果这个分量有n个节点,那 ...

  7. 【强联通分量缩点】【最短路】【spfa】bzoj1179 [Apio2009]Atm

    缩点后转化成 DAG图上的单源最长路问题.spfa/dp随便. #include<cstdio> #include<queue> #include<algorithm&g ...

  8. 【强联通分量缩点】【搜索】bzoj2208 [Jsoi2010]连通数

    两次dfs缩点,然后n次dfs暴搜. #include<cstdio> #include<vector> #include<cstring> using names ...

  9. BZOJ 1051 & 强联通分量

    题意: 怎么说呢...这种题目有点概括不来....还是到原题面上看好了... SOL: 求出强联通分量然后根据分量重构图,如果只有一个点没有出边那么就输出这个点中点的数目. 对就是这样. 哦还有论边双 ...

随机推荐

  1. Java中的toString()方法

    Java中的toString()方法 目录 Java中的toString()方法 1.    对象的toString方法 2.    基本类型的toString方法 3.    数组的toString ...

  2. IC卡的逻辑卡号和市民卡卡号

    CPU卡,IC卡等的卡号与卡在出厂时的卡号.

  3. 如何查找在CDN下的真实ip

    今天去找了一下www.bilibili.tv的IP(为什么要这样子做见),发现www.bilibili.tv使用了CDN服务直接ping找不到其真实IP(实际上不用找也可以但就是想找一下). 那我们应 ...

  4. Windows Phone 中查找可视化树中的某个类型的元素

    private void StackPanel_Tap(object sender, TappedRoutedEventArgs e) { //获取到的对象是ListBoxItem ListBoxIt ...

  5. cookie+session,会话时间设定

    很多Web程序中第一次登录后,在一定时间内(如2个小时)再次访问同一个Web程序时就无需再次登录,而是直接进入程序的主界面(仅限于本机). 实现这个功能关键就是服务端要识别客户的身份.而用Cookie ...

  6. 《搭建DNS负载均衡服务》RHEL6

    搭建DNS负载均衡环境: 1.至少三台的linux虚拟机,一台主的DNS服务器,1台副的(可以N台),1台测试机. 负载均衡有很多种,apache那样的是为了缓解人们访问网站时给服务器造成太大的压力, ...

  7. DataGridview动态添加列

    1.获取数据源(select * from table名称) 2.动态绑定数据源 private void GetTableInfo(DataTable dt) { listBh = new List ...

  8. php ftp文件上传函数--新手入门参考

    在 php编程中,用ftp上传文件比较多见,这里分享个简单入门型的ftp上传实例. <?php /** * ftp上传文件 * 学习ftp函数的用法 */ // 定义变量 $local_file ...

  9. 使用微软分布式缓存服务Velocity(Windows Server AppFabric Caching Service)

    概述 Velocity是微软推出的分布式缓存解决方案,为开发可扩展性,可用的,高性能的应用程提供支持,可以缓存各种类型的数据,如CLR对象. XML.二进制数据等,并且支持集群模式的缓存服务器.Vel ...

  10. 11g RAC r2 的启停命令概述1

    目标: 熟悉主要进程的启停顺序 了解独占模式 -excl crsctl start crs与crsctl start cluster 区别 1.熟悉主要进程的启停顺序 1.1 启动节点rac1: [r ...