Drolca

Apologize To Drolca
随笔 - 28, 文章 - 1, 评论 - 6, 引用 - 0
数据加载中……

pku 1236 Network of Schools

 

#include <iostream>
using namespace std;
#define init(I) memset(I,0,sizeof(I))
const int maxn=101;
struct edge
{
    
int data;
    edge 
*next;
}
;
edge 
*g1[maxn],*g2[maxn],*g[maxn];
int vis[maxn],path[maxn],scc[maxn],mark[maxn][maxn];
int out[maxn],in[maxn];
int n,m,cnt;

void add(edge* t[],int s,int e){
    edge 
*p;
    p
=new edge;
    p
->data=e;
    p
->next=t[s];
    t[s]
=p;
}


void dfs1(int s){
    vis[s]
=1;
    edge 
*p;
    
for(p=g1[s];p;p=p->next)
        
if(!vis[p->data])
            dfs1(p
->data);
    path[
0]++;
    path[path[
0]]=s;
}


void dfs2(int s){
    vis[s]
=1;
    scc[s]
=scc[0];
    edge 
*p;
    
for(p=g2[s];p;p=p->next)
        
if(!vis[p->data])
            dfs2(p
->data);    
}


void shrink(){
    
int s,e,k;
    init(mark);
    edge 
*p;
    
for(k=1;k<=n;k++)
        
for(p=g1[k],s=scc[k];p;p=p->next)
        
{
            e
=scc[p->data];
            
if(s!=e&&!mark[s][e])
            
{
                mark[s][e]
=1;
                add(g,s,e);
            }

        }

}


void kosaraju()
{
    
int i;
    path[
0]=scc[0]=0;
    init(vis);
    
for(i=1;i<=n;i++)
        
if(!vis[i])
            dfs1(i);
    init(vis);
    
for(i=n;i>=1;i--)
    
{
        
if(!vis[path[i]])
        
{
            scc[
0]++;
            dfs2(path[i]);
        }

    }

}

int main()
{
    
int to,i,j;
    scanf(
"%d",&n);
    
for(i=1;i<=n;i++)
        g1[i]
=g2[i]=g[i]=NULL;
    
for(i=1;i<=n;i++)
    
{
        
while(scanf("%d",&to)&&to)
        
{
            add(g1,i,to);
            add(g2,to,i);
        }

    }

    kosaraju();
    shrink();

    init(
out);
    init(
in);
    
int cnt=scc[0];
    
    
for(i=1;i<=cnt;i++)
        
for(j=1;j<=cnt;j++)
            
if(mark[i][j])
            
{
                
out[i]++;
                
in[j]++;
            }

    
if(cnt==1)
    
{
        printf(
"1\n0\n");
        
return 0;
    }

    
int t1=0,t2=0;
    
for(i=1;i<=cnt;i++)
    
{
        
if(in[i]==0) t1++;
        
if(out[i]==0) t2++;
    }

    printf(
"%d\n",t1);
    printf(
"%d\n",t1>t2?t1:t2);
    
return 0;
}

posted on 2009-08-20 17:08 Drolca 阅读(148) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理