zoj 3232 It's not Floyd Algorithm(强联通分量,缩点)
2014-01-24 21:56
411 查看
题目
/******************************************************************/
以下题解来自互联网:Juny的博客
思路核心:给你的闭包其实就是一个有向图;
方法:
1,对此图进行缩点,对于点数为n(n>1)的强连通分量最少要 n 条边,
对点数为 1 的强连通不需要边,这样计算出边数 m1 ;
2,在缩点后的有向无环图中进行反floyd,如果有边a->b,b->c,a->c那么显然a->c可以去掉,
就这样一直去除这样的边,直到不能再去为止,算出最终边数 m2;
3,m1+m2 即为答案;
这样做速度比较慢,但小草还没想出其他好的办法,希望有大牛指点……
/*****************************************************************/
View Code
/******************************************************************/
以下题解来自互联网: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 = 0; scnt = top = tot = 0; memset(first, -1, sizeof(first)); memset(DFN, 0, sizeof(DFN)); memset(num,0,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] = 1; stack[top++] = v; for(int e = first[v]; e != -1; 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] = 0; Belong[t] = scnt; //为缩点做准备的 num[scnt]++; }while(t != v); } } void solve() { for(int i = 1; i <= n; i++) if(!DFN[i]) Tarjan(i); } int main() { int i,j,map[210][210],sum1,ans,map1[210][210];//map1[][]是缩点后新建的图 while(scanf("%d",&n)!=EOF) { init(); ans=0; memset(map,0,sizeof(map)); memset(map1,0,sizeof(map1)); for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { scanf("%d",&map[i][j]); if(map[i][j]==1&&i!=j) { read_graph(i,j); } } } solve(); sum1=0; for(i=1;i<=scnt;i++) { if(num[i]>1) sum1+=num[i]; } for(int ii=1;ii<=n;ii++) { for(int jj=1;jj<=n;jj++) { if(map[ii][jj]&&Belong[ii]!=Belong[jj]) map1[Belong[ii]][Belong[jj]]=1; } } for(int ii=1;ii<=scnt;ii++) for(int jj=1;jj<=scnt;jj++) for(int kk=1;kk<=scnt;kk++) if(map1[ii][jj]&&map1[ii][kk]&&map1[kk][jj])//此处在缩点新建图 map1[ii][jj]=0; for(int ii=1;ii<=scnt;ii++) for(int jj=1;jj<=scnt;jj++) if(map1[ii][jj]) ans++; printf("%d\n",sum1+ans); } return 0; }
View Code
相关文章推荐
- TOJ 3365 ZOJ 3232 It's not Floyd Algorithm / 强连通分量
- ZOJ 3232 It's not Floyd Algorithm --强连通分量+Floyd
- ZOJ 3232 It's not Floyd Algorithm ( 暴力水过 )
- ZOJ 3232 - It's not Floyd Algorithm(强连通缩点+Floyd)
- zoj 3232 It's not Floyd Algorithm
- TOJ 3365 ZOJ 3232 It's not Floyd Algorithm / 强连通分量
- ZOJ 3795 Grouping(强联通分量 + 缩点 + Dp)
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 F.islands (强联通分量 + 缩点)
- 【最小割】【Dinic】【强联通分量缩点】bzoj1797 [Ahoi2009]Mincut 最小割
- zoj3232 It's not Floyd Algorithm
- [HAOI2006 受欢迎的牛] 强联通分量 缩点
- poj 2762 Going from u to v or from v to u? (强联通分量缩点 + 欧拉回路或通路)
- 文章标题 POJ 1236 : Network of Schools (强联通分量+缩点)
- poj 2553 zoj 1979 The Bottom of a Graph(强联通分量 Tarjan)
- HDU5409---CRB and Graph 2015多校 双联通分量缩点
- POJ 1236 Network of Schools 强联通分量 + 缩点
- 强联通分量缩点模板
- zoj 2588 Burning Bridges 联通分量
- HDU4612 Warm up(强联通分量+缩点重构图后求树的直径)
- POJ 1236 Network of Schools 强联通分量 + 缩点