现在的位置: 首页 > 综合 > 正文

poj1236 强联通分量(tarjan)

2014年01月09日 ⁄ 综合 ⁄ 共 2095字 ⁄ 字号 评论关闭


解题报告


题目

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


题目大意

:给定一个有向图,求下面两个量:

1

:最少从几个点出发能遍历全图。

2

:最少加几条边能使原图强联通。


算法

tarjan求强联通分量


思路

:“最少从几个点出发能遍历全图”的点数是将原图缩点后入度为零的点的个数。

        
 


“最少加几条边能使原图强联通”的边数是将原图缩点后出度为零的点和入读为零的点中的最大值。



:当只有一个缩点时,边数为
0.


提交情况

wrong answer
2


(边数求成了出度为零的点的个数。。)

   
        
   Accepted
1

//poj2553也是类似题

AC
code

#include <stdio.h>

#include <string.h>

 

#define MAXN 2000

#define MAXM (MAXN * MAXN)

 

struct NODE{

   
int to, next;

};

NODE edges[MAXM];

inthead[MAXN], ad;

 

intdfn[MAXN], low[MAXN], vis[MAXN], strack[MAXN],
belong[MAXN], in[MAXN], out_degree[MAXN],
in_degree[MAXN];

int times, tarjan_total, top;

 

void dfs(int
u){

   
int p;

   
low[u] = dfn[u] = times ++;

   
strack[++top] = u;

   
vis[u] = 1;

   
in[u] = 1;

   
for(p = head[u];  ~p; p =
edges[p].next){

      
if(!vis[edges[p].to]){

          
dfs(edges[p].to);

          
if(low[u] >
low[edges[p].to])

             
low[u] = low[edges[p].to];

      
}

      
else

          
if(in[edges[p].to]
&& low[u] >
low[edges[p].to]) low[u] = low[edges[p].to];

   
}

   
if(dfn[u] == low[u]){

      
tarjan_total ++;

      
belong[u] = tarjan_total;

      
in[u] = 0;

      
while((p = strack[top--]) !=
u){

          
low[p] = low[u];

          
belong[p] = tarjan_total;

          
in[p] = 0;

      
}

   
}

}

 

void tarjan(int
n){

   
int i;

   
times = 0;

   
tarjan_total = 0;

   
top = -1;

   
memset(vis, 0 ,sizeof(vis));

   
memset(in, 0, sizeof(in));

   
for(i = 1; i <= n; i
++)

      
if(!vis[i]) dfs(i);

}

 

void Getans(int
n){

   
int i, j;

   
memset(in_degree, 0, sizeof(in_degree));

   
memset(out_degree, 0, sizeof(out_degree));

   
for(i = 1; i <= n; i
++)

      
for(j = head[i]; ~j; j =
edges[j].next){

          
if(belong[i] !=
belong[edges[j].to]){

             
out_degree[belong[i]] ++;

             
in_degree[belong[edges[j].to]] ++;

          
}

      
}

   
int ans1 = 0, ans2 = 0;

   
for(i = 1; i <=
tarjan_total; i ++){

      
if(in_degree[i] == 0) ans1
++;

      
if(out_degree[i] == 0) ans2
++;

   
}

   
if(tarjan_total == 1) ans2 =
0;

   
else ans2 = ans1 >
ans2 ? ans1 : ans2;

   
printf("%d\n%d\n", ans1,
ans2);

}

 

int main(){

   
int n, t, i;

   
while(~scanf("%d", &n)){

      
ad = 0;

      
memset(head, -1, sizeof(head));

      
for(i = 1; i <= n; i
++)

          
while(~scanf("%d", &t), t){

             
edges[ad].to = t; edges[ad].next = head[i]; head[i] = ad
++;

          
}

      
tarjan(n);

      
Getans(n);

   
}

   
return 0;

}

 

 

 

抱歉!评论已关闭.