• POJ1523:SPF——题解


    http://poj.org/problem?id=1523

    这题明显就是求割点然后求割完之后的强连通分量的个数。

    割点都会求,怎么求割完的分量个数呢?

    我们可以通过万能的并查集啊!(具体做法看代码吧,方法不好叙述)

    这样我们查割点它所连的点一共隶属于几个集合即可。

    (PS:读入方式很恶心,同时请注意快速读入)

    #include<stack>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    inline int read(){
        int x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return x*w;
    }
    const int maxn=1001;
    bool dis[maxn][maxn];
    bool cut[20001];
    int dfn[maxn];
    int low[maxn];
    int fa[maxn];
    int from[maxn];
    int t;
    int big[maxn];
    int to[maxn];
    int find(int a){
        if(a==fa[a])return a;
        return fa[a]=find(fa[a]);
    }
    void tarjan(int u,int f){
        bool tong[maxn]={0};
        from[u]=f;
        t++;
        dfn[u]=t;
        low[u]=t;
        to[t]=u;
        for(int v=1;v<=maxn;v++){
        if(dis[u][v]){
            if(!dfn[v]){
            tarjan(v,u);
            low[u]=min(low[u],low[v]);
            }else if(f!=v){
            low[u]=min(low[u],dfn[v]);
            }
        }
        fa[find(u)]=find(to[low[u]]);
        }
        for(int v=1;v<=maxn;v++){
        if(dis[u][v]){
            if(!tong[find(v)]){
            tong[find(v)]=1;
            big[u]++;
            }
        }
        }
        return;
    }
    int main(){
        int u,v;
        int cnt=0;
        bool smg=0;
        while(233){
        int u=read();
        if(!u&&!smg)break;
        smg=1;
        if(!u){
            for(int i=1;i<=maxn;i++)fa[i]=i;
            tarjan(1,0);
            int rootson=0;
            bool ok=0;
            for(int i=2;i<=maxn;i++){
            int v=from[i];
            if(v==1)rootson++;
            else{
                if(low[i]>=dfn[v]&&low[i]&&dfn[i]){
                cut[v]=1;
                ok=1;
                }
            }
            }
            if(rootson>=2){
            cut[1]=1;
            ok=1;
            }
            cnt++;
            printf("Network #%d
    ",cnt);
            if(ok==0){
            printf("  No SPF nodes
    ");
            }else{
            for(int i=1;i<=maxn;i++){
                if(cut[i])printf("  SPF node %d leaves %d subnets
    ",i,big[i]);
            }
            }
            printf("
    ");
            memset(cut,0,sizeof(cut));
            memset(dfn,0,sizeof(dfn));
            memset(low,0,sizeof(low));
            memset(fa,0,sizeof(fa));
            memset(from,0,sizeof(from));
            memset(dis,0,sizeof(dis));
            memset(big,0,sizeof(big));
            memset(to,0,sizeof(to));
            t=0;
            smg=0;
            continue;
        }
        int v=read();
        dis[u][v]=dis[v][u]=1;
        }
        return 0;
    }
  • 相关阅读:
    外部存储 使用详解
    内部存储 使用详解
    SQLite 使用详解
    SharePerference 使用详解
    Preference 使用详解
    Notification 使用详解
    PopupWindow 使用详解
    Fragment 使用详解
    Dialog 使用详解
    ListView 使用详解
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/7845890.html
Copyright © 2020-2023  润新知