P2746 P2812 [USACO5.3] campus network Network of Schools [SCC condensing point]

Title Description

Some schools even into a computer network. Those schools have entered into an agreement: each school will give some other school distribution software (referred to as "receiving schools"). Note that the list even if the B school in the distribution list A, A is not necessarily in the B-school's.

You want to write a program to calculate, according to the agreement, in order to make the network all schools use the new software, new schools must accept a minimum number of copies of the Software (subtasks A). Furthermore, we wanted to determine through a school to send any new software, which will be distributed to all schools in the network. To accomplish this task, we may have to expand the school to receive lists to new members. Calculate the minimum necessary to increase the number of extensions that make us no matter which school to send new software, it will reach all the remaining schools (subtasks B). An extension is the introduction of a new member in the school receives a school list.

Resolve

In addition to this problem there are two data points outside the pit, is a board, have both stepped pit nest (nest too dishes.

Pit: 1, may be only a point, the school does not need to add any points after scc shrink extension.

2, sub-task B to obtain a larger value of the number of the number of the zero point of the zero-degree point, when the apparent spreading of these zero points, each of the zero point even we should have a zero-degree direction edge-to-point connected to it.

Reference Code

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#define N 50010
using namespace std;
inline int read()
{
    int f=1,x=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct rec{
    int next,ver;
}g[N],G[N];
int head[N],headG[N],tot,totG,n,low[N],dfn[N];
int stack[N],top,c[N],cnt,ing[N],idt,scc[N],otg[N];
bool ins[N],v[N];
inline void add(int x,int y)
{
    g[++tot].ver=y;
    g[tot].next=head[x],head[x]=tot;
}
inline void addG(int x,int y)
{
    G[++totG].ver=y;
    G[totG].next=headG[x],headG[x]=totG;
    ing[y]++;otg[x]++;
}
inline void tarjan(int x)
{
    dfn[x]=low[x]=++cnt;
    stack[++top]=x,ins[x]=1;
    for(int i=head[x];i;i=g[i].next){
        int y=g[i].ver;
        if(!dfn[y]){
            tarjan(y);
            low[x]=min(low[x],low[y]);
        }
        else if(ins[y]) low[x]=min(low[x],dfn[y]);
    }
    if(low[x]==dfn[x]){
        int y;idt++;
        do{
            y=stack[top--],ins[y]=0;
            c[y]=idt;scc[idt]++;
        }while(x!=y);
    }
}
int main()
{
    n=read();
    for(int i=1;i<=n;++i){
        int v;
        while(scanf("%d",&v)&&v!=0)
            add(i,v);
    }
    for(int i=1;i<=n;++i)
        if(!dfn[i]) tarjan(i);
    for(int x=1;x<=n;++x)
        for(int i=head[x];i;i=g[i].next){
            int y=g[i].ver;
            if(c[x]==c[y]) continue;
            addG(c[x],c[y]);
        }
    int ans1=0,ans2=0;
    for(int i=1;i<=idt;++i){
        if(ing[i]==0) ans1++;
        if(otg[i]==0) ans2++;
    }
    cout<<ans1<<endl;
    if(idt==1)
        printf("0\n");
    else cout<<max(ans1,ans2)<<endl;
    return 0; 
}

Guess you like

Origin www.cnblogs.com/DarkValkyrie/p/11305295.html