poj 1236 强连通+缩点

来源:互联网 发布:淘宝营业执照怎么办理 编辑:程序博客网 时间:2024/06/11 01:12

传送门

题意:给你一个有向图,问最少几个学校可以达到所有学校,然后又问,加多少边可以使得任意学校到达任意学校。

思路:把构成强连通的点们当作1个点处理,然后在“新图”中找到入度为0的点的个数和出度为0的点的个数。对于第一问,只要输出入度为0的点的个数即可。对于第二问,如果所以点构成1个强连通,那么不许要添加边,即输出0;否则输出max(入度为0的点的个数,出度为0的点的个数)。

#include<iostream>#include<cstdio>#include<cstring>#include<stack>using namespace std;struct Edge{    int u,v;}e[10005];int n,d[105],dfn[105],low[105],recve,next[10005],fst[105],edgenum,scnum,num,in[105],out[105],innum,outnum;bool instack[105];stack<int>st;void init(){    edgenum=0;    scnum=0;    num=0;    innum=0;    outnum=0;    memset(in,0,sizeof(in));    memset(out,0,sizeof(out));    memset(instack,0,sizeof(instack));    memset(dfn,0,sizeof(dfn));    memset(fst,-1,sizeof(fst));    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        while(scanf("%d",&recve)&&recve)        {            next[++edgenum]=fst[i];            fst[i]=edgenum;            e[edgenum].v=recve;            e[edgenum].u=i;        }    }}void tarjan(int u){    dfn[u]=low[u]=++num;    st.push(u);    instack[u]=1;    for(int i=fst[u];i!=-1;i=next[i])    {        int v=e[i].v;        if(!dfn[v])        {            tarjan(v);            low[u]=min(low[u],low[v]);        }        else if(instack[v])        {            low[u]=min(low[u],dfn[v]);        }    }    if(dfn[u]==low[u])    {        int v;        scnum++;        do        {            v=st.top();            st.pop();            instack[v]=0;            d[v]=scnum;        }while(v!=u);    }}void strongconnect(){    for(int i=1;i<=n;i++)    {        if(!dfn[i])tarjan(i);    }}void solve(){    for(int i=1;i<=n;i++)    {        for(int j=fst[i];j!=-1;j=next[j])        {            int v=e[j].v;            if(d[i]!=d[v])            {                in[d[v]]++;                out[d[i]]++;            }        }    }    for(int i=1;i<=scnum;i++)    {        if(in[i]==0)innum++;        if(out[i]==0)outnum++;    }    printf("%d\n",innum);    if(scnum==1)printf("0\n");    else printf("%d\n",max(innum,outnum));}int main(){    init();    strongconnect();    solve();    return 0;}