poj1236
http://poj.org/problem?id=1236
问题A:在网络中需要多少电脑才能使所有学校都有软件,通过强连通算法缩点,构建DAG图,图中一定有入度为0的节点,由于这种节点无法通过别的节点传送软件,所以必须放一台电脑,求出入度为0的节点个数即可。
问题B:在该网络中最少添加多少线路,使在任意节点放置电脑所有学校都可以有软件,答案是求入度为0的节点个数和入度为0的节点个数的最大值。
证明B:
1.以下所有点都是孤立的,连接两个点时,出发的边连接的是起始点中出度为0的点,终点中入度为0的点。
(1).定义当点数n=1时,如果是缩点构成的一个点必须添加一条反身边,否则不用添加边。
(2).当点数n=2时,连接两个点,缩成一个点,然后按规则(1),可得最少添加边数为2。
(3).当n>2时,通过规则(2)不断缩点,当点缩为一个时按规则(1),可得最少添加边数为n。
2.从最旁边的入度为0的节点出发与其下的最旁边的出度为0节点配对,将途中所有点包括起点和终点缩成一个点,并断开所有与其他节点连接的边,通过这样可以使DAG图形成由n(n>0)个孤立点组成的图,求最少添加边数是该图强连通,则可有1得出最少添加边数为n,由于n个孤立点都是入度为0的节点,出度为0的节点或两者配对形成的,可知n是入度为0的节点个数和入度为0的节点个数的最大值。
给出tarjan代码。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h>
2 #include <memory.h>
3 #define SIZE 101
4 #define min(a,b) ((a)<(b)?(a):(b))
5 #define max(a,b) ((a)>(b)?(a):(b))
6 struct node
7 {
8 int end;
9 node *next;
10 }edge[SIZE*(SIZE-1)/2],*head[SIZE],*t;
11 int dfn[SIZE],low[SIZE],stack[SIZE],root[SIZE];
12 int out[SIZE],in[SIZE];
13 bool is_stack[SIZE];
14 int sum,cnt,father;
15 void tarjan(int k)
16 {
17 dfn[k]=low[k]=++cnt;
18 stack[++stack[0]]=k;
19 is_stack[k]=true;
20 for(node*tmp=head[k];tmp;tmp=tmp->next)
21 {
22 if(!low[tmp->end])
23 {
24 tarjan(tmp->end);
25 low[k]=min(low[k],low[tmp->end]);
26 }
27 else if(is_stack[tmp->end])
28 low[k]=min(low[k],dfn[tmp->end]);
29 }
30 if(dfn[k]==low[k])
31 {
32 ++father;
33 do
34 {
35 root[stack[stack[0]]]=father;
36 is_stack[stack[stack[0]]]=false;
37 }
38 while(stack[stack[0]--]!=k);
39 }
40 }
41 void ini()
42 {
43 memset(is_stack,false,sizeof(is_stack));
44 memset(stack,0,sizeof(stack));
45 memset(root,0,sizeof(root));
46 memset(dfn,0,sizeof(dfn));
47 memset(low,0,sizeof(low));
48 memset(out,0,sizeof(out));
49 memset(in,0,sizeof(in));
50 }
51 int main()
52 {
53 while(scanf("%d",&sum)==1)
54 {
55 t=edge;
56 for(int i=1;i<=sum;++i)
57 {
58 head[i]=NULL;
59 for(int k;scanf("%d",&k)==1&&k;)
60 {
61 t->end=k;
62 t->next=head[i];
63 head[i]=t++;
64 }
65 }
66 father=cnt=0;
67 for(int i=1;i<=sum;++i)
68 if(!low[i])
69 tarjan(i);
70 for(int i=1,j=0;i<=sum;i++,j=0)
71 {
72 for(t=head[i];t;t=t->next)
73 if(root[i]!=root[t->end])
74 ++in[root[t->end]],++j;
75 out[root[i]]+=j;
76 }
77 if(father==1)
78 printf("1\n0\n");
79 else
80 {
81 int n=0,m=0;
82 for(int i=1;i<=father;++i)
83 {
84 if(!in[i])
85 ++n;
86 if(!out[i])
87 ++m;
88 }
89 printf("%d\n",n);
90 printf("%d\n",max(n,m));
91 }
92 ini();
93 }
94 return 0;
95 }
gabow代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h>
2 #include <memory.h>
3 #define SIZE 101
4 #define min(a,b) ((a)<(b)?(a):(b))
5 #define max(a,b) ((a)>(b)?(a):(b))
6 struct node
7 {
8 int end;
9 node *next;
10 }edge[SIZE*(SIZE-1)/2],*head[SIZE],*t;
11 int dfn[SIZE],stack1[SIZE],stack2[SIZE],root[SIZE];
12 int out[SIZE],in[SIZE];
13 int sum,cnt,father;
14 void ini()
15 {
16 memset(stack1,0,sizeof(stack1));
17 memset(stack2,0,sizeof(stack2));
18 memset(dfn,0,sizeof(dfn));
19 memset(root,0,sizeof(root));
20 memset(out,0,sizeof(out));
21 memset(in,0,sizeof(in));
22 }
23 void Gabow(int k)
24 {
25 dfn[k]=++cnt;
26 stack1[++stack1[0]]=stack2[++stack2[0]]=k;
27 for(node*tmp=head[k];tmp;tmp=tmp->next)
28 {
29 if(!dfn[tmp->end])
30 Gabow(tmp->end);
31 else if(!root[tmp->end])
32 while(dfn[stack1[stack1[0]]]>dfn[tmp->end])
33 --stack1[0];
34 }
35 if(stack1[stack1[0]]==k)
36 {
37 --stack1[0],++father;
38 do
39 root[stack2[stack2[0]]]=father;
40 while(stack2[stack2[0]--]!=k);
41 }
42 }
43 int main()
44 {
45 while(scanf("%d",&sum)==1)
46 {
47 t=edge;
48 for(int i=1;i<=sum;++i)
49 {
50 head[i]=NULL;
51 for(int k;scanf("%d",&k)==1&&k;)
52 {
53 t->end=k;
54 t->next=head[i];
55 head[i]=t++;
56 }
57 }
58 father=cnt=0;
59 for(int i=1;i<=sum;++i)
60 if(!dfn[i])
61 Gabow(i);
62 for(int i=1,j=0;i<=sum;i++,j=0)
63 {
64 for(t=head[i];t;t=t->next)
65 if(root[i]!=root[t->end])
66 ++in[root[t->end]],++j;
67 out[root[i]]+=j;
68 }
69 if(father==1)
70 printf("1\n0\n");
71 else
72 {
73 int n=0,m=0;
74 for(int i=1;i<=father;++i)
75 {
76 if(!in[i])
77 ++n;
78 if(!out[i])
79 ++m;
80 }
81 printf("%d\n",n);
82 printf("%d\n",max(n,m));
83 }
84 ini();
85 }
86 return 0;
87 }