一些学校有一个发送消息的体系,现在给你一些可以直接发送消息的一些关系(单向)然后有两个问题
(1) 问你至少向多少个学校发送消息可以让所有的学校都得到消息
(2) 问至少加多少条边可以让所有学校达到消息互通(变成强连通图)
思路:
比较简单了,我们先强连通所点,然后对于第一个问题,我们只要输出入度为0的个数,这个很好理解,对于第二个问题,我们可以输出max(入度为0的个数,出度为0的个数),这样做是因为我们可以吧度数大的先用小的补充上,剩下的就随意补充就行了,还有就是记得只有一个联通分量的时候特判一下,
PS :假如这个题目要是让输出解决方案的话也比较好弄,对于第一个,每个入度为0的点给一个,每个强连通分量《元素个数大于1的》给一个就行了。对于第二个,就是先用小的填充大的,剩下的零头随意安排。
#include<stdio.h>
#include<string.h>
#include<stack>
#define N_node 100 + 10
#define N_edge 10000 + 100
using namespace std;
typedef struct
{
int to ,next;
}STAR;
typedef struct
{
int a ,b;
}EDGE;
EDGE edge[N_edge];
STAR E1[N_edge] ,E2[N_edge];
int list1[N_node] ,list2[N_node] ,tot;
int Belong[N_node] ,Cnt;
int mark[N_node];
stack<int>sk;
void add(int a ,int b)
{
E1[++tot].to = b;
E1[tot].next = list1[a];
list1[a] = tot;
E2[tot].to = a;
E2[tot].next = list2[b];
list2[b] = tot;
}
void DFS1(int s)
{
mark[s] = 1;
for(int k = list1[s] ;k ;k = E1[k].next)
{
int to = E1[k].to;
if(mark[to]) continue;
mark[to] = 1;
DFS1(to);
}
sk.push(s);
}
void DFS2(int s)
{
mark[s] = 1;
Belong[s] = Cnt;
for(int k = list2[s] ;k ;k = E2[k].next)
{
int to = E2[k].to;
if(mark[to]) continue;
mark[to] =1;
DFS2(to);
}
}
int main ()
{
int n ,i ,j ,a;
while(~scanf("%d" ,&n))
{
memset(list1 ,0 ,sizeof(list1));
memset(list2 ,0 ,sizeof(list2));
tot = 1;
int nowid = 0;
for(i = 1 ;i <= n ;i ++)
{
while(scanf("%d" ,&a) && a)
{
add(i ,a);
edge[++nowid].a = i;
edge[nowid].b = a;
}
}
memset(mark ,0 ,sizeof(mark));
while(!sk.empty()) sk.pop();
for(i = 1 ;i <= n ;i ++)
{
if(!mark[i]) DFS1(i);
}
Cnt = 0;
memset(mark ,0 ,sizeof(mark));
while(!sk.empty())
{
int xin = sk.top();
sk.pop();
if(mark[xin]) continue;
Cnt ++;
DFS2(xin);
}
int d1[N_node] = {0};
int d2[N_node] = {0};
for(i = 1 ;i <= nowid ;i ++)
{
int a = Belong[edge[i].a];
int b = Belong[edge[i].b];
if(a == b) continue;
d1[a] ++ ,d2[b] ++;
}
int sum1 = 0 ,sum2 = 0;
for(i = 1 ;i <= Cnt ;i ++)
{
if(!d1[i]) sum1 ++;
if(!d2[i]) sum2 ++;
}
if(Cnt == 1)
{
printf("1
0
");
continue;
}
printf("%d
" ,sum2);
sum1 > sum2 ? printf("%d
" ,sum1) : printf("%d
" ,sum2);
}
return 0;
}