P2746 [USACO5.3]校园网Network of Schools - Tarjan

->

任务A:最少选择多少点能够遍历整张有向图。

任务B:最少添加多少条有向边使整张图变为一个强连通图。

A->先用Tarjan将所有scc缩点,缩点后入度为0的点的个数即为任务A的答案,因为其他点可以由入度为零的点遍历到。

注意:

1、当n=1时,只有一个点,此时任务A的答案为1,任务B的答案为0。

2、当给定图已经是强连通图时,入度为0的点为0,此时任务A和任务B的答案都为0。

B->Tarjan缩点后,我们得到了一张有向无环图(不一定连通)。贪心地想,我们可以将每一个出度为0的点,向入度为0的点连边,这样最少添加的有向边的数量=max{入度为0的点的个数,出度为0的点的个数},而不是两种点的数量之和。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100+10,M=10000;
struct node{
    int to,nxt;
}e[M];
int head[N],tot;
void add(int u,int v){
    e[++tot]=(node){v,head[u]};
    head[u]=tot;
}
struct ed{
    int u,v;
}E[M];
int dfn[N],low[N],idx;
int s[N],top;
bool ins[N];
int col[N],cnt;
void tarjan(int u){
    dfn[u]=low[u]=++idx;
    s[++top]=u,ins[u]=1;
    for(int i=head[u];i;i=e[i].nxt){
        int v=e[i].to;
        if(!dfn[v]){
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(ins[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        cnt++;
        while(s[top]!=u){
            ins[s[top]]=0;
            col[s[top]]=cnt;
            top--;
        }
        ins[u]=0;
        col[u]=cnt;
        top--;
    }
}
int in[N],out[N];
int main(){
    int n;
    int m=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        int x;
        while(1){
            scanf("%d",&x);
            if(!x) break;
            add(i,x);
            E[++m]=(ed){i,x};
        }
    }
    for(int i=1;i<=n;i++){
        if(!dfn[i]) tarjan(i);
    }
    if(cnt==1) {
        printf("1\n0");return 0;
    }
    memset(head,0,sizeof(head));
    tot=0;
    memset(e,0,sizeof(e));
    for(int i=1;i<=m;i++){
        int u=E[i].u,v=E[i].v;
        if(col[u]!=col[v]){
            add(col[u],col[v]);
            in[col[v]]++;
            out[col[u]]++;
        }
    }
    int taskA=0,taskB=0;
    int indy0=0,outdy0=0;
    for(int i=1;i<=cnt;i++){
        if(!in[i]) taskA++,indy0++;//入度为0的点数
        if(!out[i]) outdy0++;//出度为0的点数
    } 
    taskB=max(indy0,outdy0);
    printf("%d\n%d",taskA,taskB);
}

猜你喜欢

转载自www.cnblogs.com/Loi-Brilliant/p/9124657.html
今日推荐