POJ 1236 학교 네트워크 (강 연통 분량)

제목: POJ 1236
이 문제 의 대 의 는 최소한 몇 시 에 메 시 지 를 보 내 면 어느 점 에서 든 메 시 지 를 받 을 수 있 고 최소한 몇 개의 변 을 추가 하면 그림 을 연결 그림 으로 만 들 수 있다 는 것 이다.첫 번 째 문제 에 대해 서 는 입 도 0 의 강 한 연결 블록 의 블록 수 를 구 할 수 있다. 입 도 0 의 강 한 연결 블록 만 외부 에서 정 보 를 받 아들 일 수 없 기 때문에 하나의 입 도 를 가지 고 있 으 면 전체 연결 블록 이 정 보 를 받 을 수 있 기 때문이다.두 번 째 문 제 는 수입 도가 0 인 강 한 연결 블록 과 출 도 0 인 강 한 연결 블록 의 개수 의 최대 치 를 구 하 는 것 이다.
코드 는 다음 과 같 습 니 다:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include <set>
#include <algorithm>

using namespace std;
int head[200], cnt, index, top, ans, cntin, cntout, in[200], out[200];
int dfn[200], belong[200], instack[200], stak[200], low[200];
struct node
{
    int u, v, next;
} edge[100000];
void add(int u, int v)
{
    edge[cnt].v=v;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}
void init()
{
    memset(head,-1,sizeof(head));
    cnt=0;
    memset(instack,0,sizeof(instack));
    memset(dfn,0,sizeof(dfn));
    top=index=ans=0;
    cntin=cntout=0;
    memset(in,0,sizeof(in));
    memset(out,0,sizeof(out));
}
void tarjan(int u)
{
    dfn[u]=low[u]=++index;
    instack[u]=1;
    stak[++top]=u;
    for(int i=head[u]; i!=-1; i=edge[i].next)
    {
        int v=edge[i].v;
        if(!dfn[v])
        {
            tarjan(v);
            low[u]=min(low[v],low[u]);
        }
        else if(instack[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u])
    {
        ans++;
        while(1)
        {
            int v=stak[top--];
            belong[v]=ans;
            instack[v]=0;
            if(u==v) break;
        }
    }
}
int main()
{
    int n, i, j, a;
    scanf("%d",&n);
    init();
    for(i=1; i<=n; i++)
    {
        while(scanf("%d",&a)&&a)
        {
            add(i,a);
        }
    }
    for(i=1; i<=n; i++)
    {
        if(!dfn[i])
            tarjan(i);
    }
    if(ans==1)
        printf("1
0
"); else { for(i=1; i<=n; i++) { for(j=head[i]; j!=-1; j=edge[j].next) { int v=edge[j].v; if(belong[i]!=belong[v]) { in[belong[v]]++; out[belong[i]]++; } } } for(i=1; i<=ans; i++) { if(!in[i]) cntin++; if(!out[i]) cntout++; } printf("%d
%d
",cntin,max(cntin,cntout)); } return 0; }

좋은 웹페이지 즐겨찾기