Kuangbin带你飞-专题九连通图

目录

1.POJ1236 Network of Schools(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

猜你喜欢

转载自www.cnblogs.com/overrate-wsj/p/12427969.html