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

 

posted @ 2020-03-06 17:57  overrate_wsj  阅读(144)  评论(0编辑  收藏  举报