[USACO5.3]校园网Network of Schools

来源:互联网 发布:豆瓣读书软件 编辑:程序博客网 时间:2024/05/21 13:53

Luogu P2746

任务A:

需要求最多在多少学校发送新软件,其实就是求缩点后入度为0的个数(如果入度不为0就可以从其他学校传过来)

任务B:

需要添多少条边才能形成使所有点都可以被某个点到达,所以对于每个出度为 0 的点,需要拓展一条出边,对于每个入度为 0 的点,需要拓展一条入边,为了减少拓展边数,可以将所有出度为 0 的点拓展出边到某个入度为 0 的点的上,最后答案即为 max(入度为0点数,出度为0点数)

当只有一个强连通分量时,由于入度为 0 的点和出度为 0 的点数都为 1,所以需要特判一下。

#include<cstdio>#include<algorithm>using namespace std;struct edge{    int from,to,next;}e[10005];struct edge2{    int to,next;}g[10005];int head[105],tot,head2[105],tot2,low[105],dfn[105],color[105],col_num,dfs_clock,sta[105],top,indgr[105],oudgr[105];bool isin[105];void Add(int from,int to){    e[++tot].next = head[from];    e[tot].to = to;    e[tot].from = from;    head[from] = tot;}void tarjan(int u){    low[u]=dfn[u]=++dfs_clock;    isin[u]=true;    sta[++top]=u;    for(int i=head[u];i;i=e[i].next)    {        int v=e[i].to;        if(!dfn[v])        {            tarjan(v);            low[u]=min(low[u],low[v]);        }        else if(isin[v])        {            low[u]=min(low[u],dfn[v]);        }    }    if(low[u]==dfn[u])    {        isin[u]=false;        color[u]=++col_num;        while(sta[top]!=u)        {            int v=sta[top];            color[v]=col_num;            isin[v]=false;            --top;        }        --top;    }}int main(){    int n;    scanf("%d",&n);    for(int u=1;u<=n;++u)    {        int v;        scanf("%d",&v);        while(v)        {            Add(u,v);            scanf("%d",&v);        }    }    for(int i=1;i<=n;++i)    {        if(!dfn[i])        {            dfs_clock=0;            tarjan(i);        }    }    for(int i=1;i<=tot;++i)    {        int u=e[i].from,v=e[i].to;        if(color[u]!=color[v])        {            ++indgr[color[v]];            ++oudgr[color[u]];        }    }    int insum=0,ousum=0;    for(int i=1;i<=col_num;++i)    {        if(indgr[i]==0)        {            ++insum;        }        if(oudgr[i]==0)        {            ++ousum;        }    }    printf("%d\n",insum);    if(col_num==1) puts("0");    else printf("%d\n",max(insum,ousum));    return 0;}
原创粉丝点击