luogu P2746 [USACO5.3]校园网Network of Schools 题解
阅读原文时间:2023年07月09日阅读:1

前言:

火星题。。。

但是我调了半天,最后看了题解才明白。

Wtcl

解析:

显然先缩个点。

第一问,就是问多少入度为0的点。

第二问,抽象一下就是要添加一些边,让一个DAG变成一个SCC,求最小边数。

答案就是max(入度0的数量,出度0的数量)

震惊,我竟然没看出来,活到爆!

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn=1000000+10;
#define gc() (p1 == p2 ? (p2 = buf + fread(p1 = buf, 1, 1 << 20, stdin), p1 == p2 ? EOF : *p1++) : *p1++)
#define read() ({ register int x = 0, f = 1; register char c = gc(); while(c < '0' || c > '9') { if (c == '-') f = -1; c = gc();} while(c >= '0' && c <= '9') x = x * 10 + (c & 15), c = gc(); f * x; })
char buf[1 << 20], *p1, *p2;
int n,cnt,tot,top,ss,Time,sss;
struct node{
    int to,nxt;
}edge[maxn<<1];
int head[maxn],belong[maxn],dfn[maxn],low[maxn],Stack[maxn],ind[maxn],outd[maxn];
bool vis[maxn];
void add(int from,int to){
    edge[++cnt].to=to;
    edge[cnt].nxt=head[from];
    head[from]=cnt;
}
void tarjan(int u){
    if(dfn[u]) return;
    dfn[u]=low[u]=++Time;
    vis[u]=1;
    Stack[++top]=u;
    for(int i=head[u];i;i=edge[i].nxt){
        int v=edge[i].to;
        if(!dfn[v]){
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }else if(vis[v]) low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        tot++;
        while(Stack[top+1]!=u){
            int t=Stack[top];
            top--;
            vis[t]=0;
            belong[t]=tot;
        }
    }
}
void Solve(){
    scanf("%d",&n);
    for(int i=1,x;i<=n;++i){
        while(1){
            scanf("%d",&x);
            if(x==0) break;
            add(i,x);
        }
    }
    for(int i=1;i<=n;++i) tarjan(i);
    for(int u=1;u<=n;++u){
        for(int i=head[u];i;i=edge[i].nxt){
            int v=edge[i].to;
            if(belong[u]==belong[v]) continue;
            ind[belong[v]]++;
            outd[belong[u]]++;
        }
    }
    for(int i=1;i<=tot;++i) if(ind[i]==0) ss++;
    for(int i=1;i<=tot;++i) if(outd[i]==0) sss++;
    int ans;
    if(tot==1) ans=0;
    else ans=max(ss,sss);
    printf("%d\n%d\n",ss,ans);
}
int main(){
    Solve();
    return 0;
}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章