poj 1236 Network of Schools

http://poj.org/problem?id=1236

题意:1.要求出至少发分配多少站点,使所有点都能收到,即求入度为0的分量。

        2.求要添加多少点,使任意一个点发送物品,其他点都能收到物品,即求Max(入度为0的分量个数,出度为0的分量个数)。

注意单点的情况.

View Code
#include<string.h>
#include<stdio.h>
#include<iostream>
#include<stack>
#include<utility>
using namespace std;
const int maxn = 105;
struct nd
{
        int u,v,next;
}edge[maxn*100];
int head[maxn],ecnt,idx,cnt;
int dfn[maxn],low[maxn],vis[maxn],in[maxn],out[maxn],belong[maxn];
stack<int>st;
void add(int u,int v)
{
        edge[ecnt].u = u;
        edge[ecnt].v = v;
        edge[ecnt].next = head[u];
        head[u] = ecnt++;
}

void tarjan(int u)
{
        int i,v;
        dfn[u] = low[u] = ++idx;
        st.push(u);
        vis[u] = 1;
        for(i = head[u]; i != -1; i = edge[i].next)
        {
                v = edge[i].v;
                if(!dfn[v]){
                        tarjan(v);
                        low[u] = min(low[v],low[u]);
                }else if(vis[v]) low[u] = min(dfn[v],low[u]);
        }
        if(dfn[u]==low[u]){
                cnt++;
                do{
                        v = st.top();
                        st.pop();
                        vis[v] = 0;
                        belong[v] = cnt;
                }while(v!=u);
        }
}

int main()
{
        int i,j,k,t,n,u,v;
        while(scanf("%d",&n)==1)
        {
                memset(head,-1,sizeof(head));
                memset(vis,0,sizeof(vis));
                memset(dfn,0,sizeof(dfn));
                memset(low,0,sizeof(low));
                memset(in,0,sizeof(in));
                memset(out,0,sizeof(out));
                memset(belong,0,sizeof(belong));
                ecnt = 0; idx = 0; cnt=0;
                for(i = 1; i <= n; ++ i)
                        while(scanf("%d",&v)&&v) add(i,v);
                for(i = 1; i <= n; ++ i) if(!dfn[i])tarjan(i);
                int c1 = 0,c2 = 0;
                for(i = 0; i < ecnt; ++ i)
                {
                        u = edge[i].u;
                        v = edge[i].v;
                        u = belong[u];
                        v = belong[v];
                        if(u!=v){ in[v] = 1; out[u] = 1; }
                }
                for(i = 1; i <= cnt; ++ i){ if(!in[i])c1++; if(!out[i])c2++; }
                if(cnt==1){puts("1\n0"); continue;}
                printf("%d\n%d\n",c1,max(c1,c2));
        }
        return 0;
}

posted on 2012-06-27 19:53  aigoruan  阅读(123)  评论(0)    收藏  举报

导航