ccf模拟题 201709-4 通信网络(缩点,dfs)
2017-10-13 21:37
417 查看
有小伙伴问这个问题,就写了一发给他,结果我写的得了95,他仿照我写的得了100,很蛋疼,调了一下,发现tarjan里面写错个变量。
思路:缩点,重新建两个图,正向一个,反向一个,每个点dfs一发即可。O(n^2)
思路:缩点,重新建两个图,正向一个,反向一个,每个点dfs一发即可。O(n^2)
#include <stdio.h> #include <string.h> #include <vector> using namespace std; const int MAXN = 1010; const int MAXM = 10100; struct Edge { int to,next; } edge[MAXM]; int head[MAXN],tot; int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN]; int degree[MAXN]; int Index,top; int scc; bool Instack[MAXN]; int num[MAXN]; void addedge(int u, int v) { edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; } void Tarjan(int u) { int v; Low[u] = DFN[u] = ++Index; Stack[top++] = u; Instack[u] = true; for(int i = head[u]; i != -1; i = edge[i].next) { v = edge[i].to; if(!DFN[v]) { Tarjan(v); if(Low[u] > Low[v]) Low[u] = Low[v]; } else if(Instack[v] && Low[u] > DFN[v]) Low[u] = DFN[v]; } if(Low[u] == DFN[u]) { scc++; do { v = Stack[--top]; Instack[v] = false; Belong[v] = scc; num[scc]++; } while(v != u); } } void init() { memset(degree,0,sizeof(degree)); memset(DFN,0,sizeof(DFN)); memset(Instack,false,sizeof(Instack)); memset(num,0,sizeof(num)); Index = scc = top = 0; } void solve(int n) { init(); for(int i = 1; i <= n; ++i) if(!DFN[i]) Tarjan(i); } vector<int> G1[MAXN],G2[MAXN]; bool vis1[MAXN],vis2[MAXN]; int cnt; void dfs1(int u) { cnt++; for(int i = 0; i < G1[u].size(); ++i) { int v = G1[u][i]; if(vis1[v]) continue; vis1[v] = true; dfs1(v); } } void dfs2(int u) { cnt++; for(int i = 0; i < G2[u].size(); ++i) { int v = G2[u][i]; if(vis2[v]) continue; vis2[v] = true; dfs2(v); } } int res; void rebuild(int n) { int u,v; for(int i = 1; i <= n; ++i) { for(int j = head[i]; j != -1; j = edge[j].next) { u = Belong[i]; v = Belong[edge[j].to]; if(u != v) { G1[u].push_back(v); G2[v].push_back(u); } } } res = 0; for(int i = 1; i <= scc; ++i) { memset(vis1,0,sizeof(vis1)); memset(vis2,0,sizeof(vis2)); cnt = 0; vis1[i] = vis2[i] = true; dfs1(i); dfs2(i); if(cnt == scc+1) res += num[i]; } } int n,m; int main() { scanf("%d %d",&n,&m); int u,v; tot = 0; memset(head,-1,sizeof(head)); for(int i = 0; i < m; ++i) { scanf("%d %d",&u,&v); addedge(u,v); } solve(n); rebuild(n); printf("%d\n",res); return 0; }
相关文章推荐
- CCF CSP认证 题解:201709-4 通信网络 DFS(Java语言原创)
- 【图论--DFS】CCF 201709-4 通信网络
- CCF考试——201709-4通信网络
- ccf 201709-4 通信网络 java 100分
- CCF 201709-4 通信网络 Java
- CCF 201709-4 通信网络
- CCF-CSP 通信网络 JAVA 201709-4 100分
- ccf 201709-4 通信网络 BFS遍历
- 201709-4 通信网络 ccf
- CCF 201709-4 通信网络
- CCF CSP 201709-4 通信网络
- ccf 2017 09 4 通信网络
- CCF 通信网络
- CCF 201709-4(DFS)
- [CCF CSP201709-4通信网络]缩点+拓扑+bitset
- ccf认证题-网络延时(求树的直径,dfs)
- ccf 2017-09-04 通信网络 图的遍历
- ccf 网络延时(dfs)
- 网络通信安全基础与信息加密交换原理及示例
- 网络通信