#10093. 「一本通 3.5 练习 1」网络协议(tarjan+度数分析)

libreoj10093:

#include
typedef long long LL;
using namespace std;
const int maxn=1e3+10;
const LL mod=998244353;
inline int read()
{
	int X=0; bool flag=1; char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
	while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
	if(flag) return X;
	return ~(X-1);
}
int dfn[maxn],low[maxn],cnt;
int bcc[maxn],scc;
stack<int> st;
int ins[maxn];
vector<int> G[maxn],g[maxn];
int in[maxn],out[maxn];
int n;
map<pair<int,int>,int> mp;
void init()
{
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(ins,0,sizeof(ins));
    memset(bcc,0,sizeof(bcc));
    memset(in,0,sizeof(in));
    memset(out,0,sizeof(out));
    cnt=0;
    scc=0;
    while(!st.empty()){
        st.pop();
    }
    for(int i=0;i<=n;i++){
        G[i].clear();
    }
    for(int i=0;i<=n;i++){
        g[i].clear();
    }
}
void tarjan(int u)
{
    dfn[u]=low[u]=++cnt;
    st.push(u);
    ins[u]=1;
    int len=G[u].size();
    for(int i=0;i<len;i++){
         int to=G[u][i];
         if(!dfn[to]){
            tarjan(to);
            low[u]=min(low[u],low[to]);
         }
         else
         if(ins[to]){
            low[u]=min(low[u],dfn[to]);
         }
    }
    if(dfn[u]==low[u]){
        ++scc;
        while(1){
            int pre=st.top();
            st.pop();
            ins[pre]=0;
            bcc[pre]=scc;
            if(pre==u)break;
        }
    }
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        int v;
        while(scanf("%d",&v)&&v){
            G[i].push_back(v);
        }
    }
    for(int i=1;i<=n;i++){
        if(!dfn[i]){
            tarjan(i);
        }
    }
    mp.clear();
    for(int i=1;i<=n;i++){
        for(int j=0;j<G[i].size();j++){
            int u=bcc[i],v=bcc[G[i][j]];
            pair<int,int> pre=make_pair(u,v);
            if(u!=v&&!mp[pre]){
                 g[u].push_back(v);
                 in[v]++;
                 out[u]++;
                 mp[pre]++;
            }
        }
    }
    /*printf("in:\n");
    for(int i=1;i<=scc;i++){
        printf("%d ",in[i]);
    }
    cout<
    /*for(int i=1;i<=scc;i++){
        for(int j=0;j
    //printf("lllll\n");
    int a=0,b=0;
    for(int i=1;i<=scc;i++){
        if(in[i]==0){
            a++;
        }
        if(out[i]==0){
            b++;
        }
    }
    int x,y;
    if(scc==1){
        x=1;y=0;
    }
    else{
        x=a;y=max(a,b);
    }
    printf("%d\n%d",x,y);
    return 0;
}



你可能感兴趣的:(#10093. 「一本通 3.5 练习 1」网络协议(tarjan+度数分析))