LA 4287,HDU 2767 求有向图强连通分量个数和各节点属于哪个分量




//求有向图强连通分量个数和各节点属于哪个分量
//此题是求最少添加几条有向边使整个图成为强连通图
#include <iostream>
#include <vector>
#include <stack>
#include <cstring>

using namespace std;

const int maxn=20005;

vector<int> g[maxn];
stack<int> st;
int ord[maxn],low[maxn],id[maxn]; //id[i]记录第i个节点属于哪个连通分量
int cnt,scnt; //cnt记录访问次序,scnt是强连通分量个数
int n,m;
int indegree[maxn];
int outdegree[maxn];

void Tarjan(int e)
{
    int t;
    int min=low[e]=ord[e]=cnt++;
    st.push(e);
    for(int i=0;i<g[e].size();++i)
    {
        t=g[e][i];
        if(ord[t]==-1) Tarjan(t);
        if(low[t]<min) min=low[t];
    }
    if(min<low[e]) {low[e]=min; return;}
    do{
        id[t=st.top()]=scnt;
        low[t]=n+1;
        st.pop();
    }while(t!=e);
    ++scnt;
}

void Search()
{
    memset(ord,-1,sizeof(ord));
    cnt=0; scnt=0;
    for(int i=0;i<n;++i)
        if(ord[i]==-1) Tarjan(i);
}

void base_vertex()
{
    Search();
    int t;
    memset(indegree,0,sizeof(indegree));
    memset(outdegree,0,sizeof(outdegree));
    for(int i=0;i<n;++i)
    {
        for(int j=0;j<g[i].size();++j)
        {
            t=g[i][j];
            if(id[t]!=id[i])
            {
                ++indegree[id[t]];
                ++outdegree[id[i]];
            }
        }
    }
}

int main()
{
    int t; cin>>t;//t是样例组数
    int in,out;
    int u,v;
    while(t--)
    {
        cin>>n>>m;//n为顶点数,m为有向边数
        for(int i=0;i<n;++i)
            g[i].clear();
        for(int i=0;i<m;++i)
        {
            cin>>u>>v;
            g[u-1].push_back(v-1);//下标从0到n-1
        }
        base_vertex();
        in=0;out=0;
        if(scnt==1) {cout<<0<<endl; continue;}
        for(int i=0;i<scnt;++i)
        {
            if(indegree[i]==0) ++in;
            if(outdegree[i]==0) ++out;
        }
        cout<<(in>out?in:out)<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值