邻接表割点、割边

割点

代码如下:

#include 
#include 
#include 
#include 
#include 
using namespace std;
#define N 10000
vector<int>G[N+10];
int low[N+10], num[N+10], vis[N+10];
int n, m, index;//index为走过的点的编号
void Cutpoint(int cur, int father)
{
    index++;
    num[cur] = index;
    low[cur] = index;
    for(int i = 0; i < G[cur].size(); i++)
    {
        int cnode = G[cur][i];
        if(num[cnode] == 0)
        {
            Cutpoint(cnode, cur);
            low[cur] = min(low[cur], low[cnode]);
            if(num[cur] <= low[cnode])//割边的话改为if(num[cur] < low[cnode])即可
                vis[cur] = 1;         //割边: printf("%d %d\n", cur, cnode);
        }
        else if(cnode != father)
            low[cur] = min(low[cur],num[cnode]);
    }
    return ;
}
int main()
{
    while(~scanf("%d %d", &n, &m))
    {
        memset(vis, 0, sizeof(vis));
        memset(num, 0, sizeof(num));
        int a, b;
        for(int i = 0; i <= n; i++)
            G[i].clear();
        while(m--)
        {
            scanf("%d %d", &a, &b);
            G[a].push_back(b);
            G[b].push_back(a);
        }
        index = 0;
        Cutpoint(1, 1);
        int ans = 0;
        for(int i = 1; i <= n; i++)
            if(vis[i])
            {
                ans++;
                printf("%d ", i);
            }
        printf("%d\n", ans);
    }
    return 0;
}

你可能感兴趣的:(图论相关(代码))