⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpp1.cpp

📁 求强连通分量
💻 CPP
字号:
#include <stdio.h>
#include <string.h>
#define G_size 100000
#define V_size 11000
 
typedef struct Graph
{
    int id;
    int next;
} Graph;
 
typedef struct Edge
{
    int s;
	int e;
} Edge;
 
Edge E[G_size];
Graph GA[G_size], GT[G_size];
int N, M;
int G_end;//最后一个节点的序号
int order[V_size], id[V_size], vis[V_size], in[V_size];//order[]:记录dfs过程结束访问点的顺序
int cnt, scnt, pos;
 
void Insert(int s, int e) //建立原图和逆图
{
    int p;
    p = s;
    while (GA[p].next)//建立原图
        p = GA[p].next;
    GA[G_end].id = e;
    GA[p].next = G_end;
 
    p = e;
    while (GT[p].next)//建立逆图
        p = GT[p].next;
    GT[G_end].id = s;
    GT[p].next = G_end;
 
    G_end++;
}
 
void DFST(int x) //对逆图进行搜索
{
    int p, q;
    vis[x] = 1;//置已访问标记
    p = GT[x].next; 
while (p)//当邻接顶点存在时循环
    {
        q = GT[p].id;
        if (!vis[q])//是未访问的结点
            DFST(q);//递归搜索
        p = GT[p].next;//取下一个邻接顶点
    }
    order[cnt++] = x;
}
 
void DFSA(int x) //对原图进行搜索
{
    int p, q;
    vis[x] = 1;//置已访问标记
    id[x] = cnt;
    p = GA[x].next;
    while (p)
    {
        q = GA[p].id;
        if (!vis[q])//是未访问的结点
            DFSA(q);//递归搜索
        p = GA[p].next;//取下一个邻接顶点
   }
}
 
void Solve() //主要过程
{
    int s, e;
    int i;
 
    memset(GA, 0, sizeof(GA));//初始化
    memset(GT, 0, sizeof(GT));//初始化
    memset(E, 0, sizeof(E));//初始化
    G_end = N + 1;
 
    for (i = 0; i < M; i++)
    {
        scanf("%d %d", &s, &e);//s是权值,e是序号
        E[i].s = s - 1;
        E[i].e = e - 1;
        Insert(s - 1, e - 1);
    }
 
    memset(vis, 0, sizeof(vis));//初始化
    cnt = 0;
    for (i = 0; i < N; i++)
    {
        if (!vis[i])
        {
            DFST(i);
        }
    }
 
    memset(vis, 0, sizeof(vis)); //初始化
	cnt = 0;
    for (i = N - 1; i >= 0; i--)
    {
        if (!vis[order[i]])
        {
            DFSA(order[i]);
            cnt++;
        }
    }
 
    for (i = 0; i < M; i++)
    {
        s = id[E[i].s];
        e = id[E[i].e];
        if (s != e)
        {
            in[s]++;
        }
    }
    scnt = cnt;
    cnt = 0;
    for (i = 0; i < scnt; i++)
    {
        if (in[i] == 0)
        {
            pos = i;
            cnt++;
        }
    }
    if (cnt != 1)
    {
        printf("0\n");
    }
    else
    {
        cnt = 0;
        for (i = 0; i < N; i++)
        {
            if (in[id[i]] == pos)
            {
                cnt++;
            }
        } printf("%d\n", cnt);
    }
}
 
int main()
{
    while (EOF != scanf("%d %d", &N, &M))
        Solve();
    return 0;
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -