struct Node{
int v,next;
}edge[M<<1];//原图的边
int now[M],init[M];//新图的邻接表表头,原图的邻接表表头
int pre[M],Index;//访问顺序
int low[M],idx[M],hash[M];//追溯的最早次序,点在新图的id,哈希新图的边
int ss[M],top;//放节点的栈
int n , nn , len;//原图大小,新图大小,边数(旧+新)
int m,_in[M],_out[M];//旧边数,新图入度,新图出度
void dfs(int u) {
pre[u] = low[u] = Index ++;
ss[++top] = u;
for(int i = init[u] ; i != -1 ; i = edge[i].next) {
int v = edge[i].v;
if(pre[v] == -1) {
dfs(v);
low[u] = min(low[u] , low[v]);
} else if(idx[v] == -1) {
low[u] = min(low[u] , pre[v]);
}
}
if(pre[u] == low[u]) {
int v = -1;
nn++;
while(u != v) {
v = ss[top--];
idx[v] = nn;
}
now[nn] = -1;
}
}
void Trajan() {
memset(pre,-1,sizeof(int)*(n+1));
memset(idx,-1,sizeof(int)*(n+1));
Index = top = nn = 0;
ss[0] = -1;
for(int i=1;i<=n;i++) if(pre[i] == -1) dfs(i);
}
void shrink(){//缩点+求出缩点之后的入度出度
memset(_in,0,sizeof(int)*(nn+1));
memset(_out,0,sizeof(int)*(nn+1));
memset(hash,-1,sizeof(int)*(nn+1));
for(int u=1;u<=n;u++) {
for(int i = init[u] ; i != -1 ; i = edge[i].next) {
int v = edge[i].v;
if(idx[u] != idx[v] && hash[idx[u]] != idx[v]) {
hash[idx[u]] = idx[v];
edge[len].next = now[ idx[u] ];
edge[len].v = idx[v];
now[ idx[u] ] = len++;
_in[idx[v]]++,_out[idx[u]]++;
}
}
}
}
[gotoac]强连通+缩点
最新推荐文章于 2022-05-18 19:18:44 发布