zoukankan      html  css  js  c++  java
  • Kuangbin带你飞-专题九连通图

    目录

    1.POJ1236 Network of Schools(Tarjan缩点)

    2.UVA315 Network(Tarjan求割点)

    POJ1236 Network of Schools(Tarjan缩点)

    题意:

    给一张有向图,问你至少要选多少点,从这些点出发可以遍历整个图,最少要加多少条边才能使整个图联通

    思路:

    先对整个图进行缩点,然后统计出缩点之后每个点的出度与入度

    第一个答案就为入度为0的点,第二个答案就为出度为0跟入度为0的点个数的最大值,注意要特判缩点之后点为1的情况

    #include<iostream>
    #include<algorithm>
    #include<vector> 
    #include<cstdio>
     using namespace std;
     const int maxn=105;
     vector<int> a[maxn];
     int dfs[maxn],low[maxn],s[maxn],n,flag[maxn],tot,cnt[maxn],t,k,color[maxn];
     int in[maxn],out[maxn];
     void tarjan(int x)
     {
         dfs[x]=low[x]=++tot;
         s[++k]=x;
         flag[x]=1;
         for(int i=0;i<a[x].size();i++){
             if(!dfs[a[x][i]]){
                 tarjan(a[x][i]);
                 low[x]=min(low[x],low[a[x][i]]);
             }
            else if(flag[a[x][i]])
                low[x]=min(low[x],dfs[a[x][i]]);
         }
        if(dfs[x]==low[x]){
            t++;
            do{
                color[s[k]]=t,cnt[t]++;
                flag[s[k--]]=0;
            }while(x!=s[k+1]);
        }
     }
     int main()
     {
         scanf("%d",&n);
         for(int i=1;i<=n;i++){
             int temp;
             while(scanf("%d",&temp)&&temp)
                 a[i].push_back(temp);
         }
        for(int i=1;i<=n;i++){
            if(!dfs[i])
                tarjan(i);
        }
        for(int i=1;i<=n;i++){
            for(int j=0;j<a[i].size();j++){
                if(color[i]!=color[a[i][j]]){
                    in[color[a[i][j]]]++;
                    out[color[i]]++;
                }
            }
        }
        int ans1=0,ans2=0;
        for(int i=1;i<=t;i++){
            if(in[i]==0) ans1++;
            if(out[i]==0) ans2++;
        }
        cout<<ans1<<endl;
        if(t==1) cout<<0;
        else cout<<max(ans1,ans2)<<endl;
     }
    View Code

    UVA315 Network(Tarjan求割点)

    题意:

    求割点数量

    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<sstream>
     using namespace std;
     typedef long long ll;
     const int maxn=105+10;
     vector<int> a[maxn];
     int low[maxn],dfs[maxn],tot,ans,cnt[maxn];
     void tarjan(int u,int fa)
     {
         dfs[u]=low[u]=++tot;
         int son=0;
         for(int i=0;i<a[u].size();i++){
             int v=a[u][i];
             if(!dfs[v]){
                tarjan(v,fa);
                 low[u]=min(low[u],low[v]);
                 if(low[v]>=dfs[u]&&u!=fa)    cnt[u]=1;
                 if(u==fa) son++;
             }
            low[u]=min(low[u],dfs[v]);
         }
        if(u==fa&&son>1) cnt[fa]=1;
     }
     int main()
     {
         int n,temp;
         while(scanf("%d",&n)&&n){
             for(int i=1;i<=n;i++){
                 a[i].clear();
                 dfs[i]=low[i]=cnt[i]=0;
             } 
             tot=0;
             ans=0;
             string s;
             while(getline(cin,s)){
                if(s=="0")break;
                istringstream ss(s);
                int b;
                ss>>b;
                int t;
                while(ss>>t){
                    a[b].push_back(t);
                    a[t].push_back(b);
                }
            }
            for(int i=1;i<=n;i++){
                if(!dfs[i])
                tarjan(i,i);
            }
            for(int i=1;i<=n;i++) if(cnt[i]) ans++;
            cout<<ans<<endl;
         }
        return 0;
      } 
    View Code
  • 相关阅读:
    Makefile 运行
    fortran中//表示什么啊?双斜杠
    如何设置EXCEL打印范围
    Makefile学习_简介
    小白初学Ioc、DI、Castle Windsor依赖注入,大神勿入(不适)
    小白初学ABP框架,着实累啊
    职场初体验
    3.8.1 块作用域
    3.8 控制流程
    3.7.3 文件输入与输出
  • 原文地址:https://www.cnblogs.com/overrate-wsj/p/12427969.html
Copyright © 2011-2022 走看看