题目链接

题意:学校有一些单向网络,现在需要传一些文件

求:1,求最少需要向几个学校分发文件才能让每个学校都收到,

  2,需要添加几条网络才能从任意一个学校分发都可以传遍所有学校。

解题思路(参考大神的):

—        1. 求出所有强连通分量

—        2. 每个强连通分量缩成一点,则形成一个有向无环图DAG。

—        3. DAG上面有多少个入度为0的顶点,问题1的答案就是多少

在DAG上要加几条边,才能使得DAG变成强连通的,问题2的答案就是多少

加边的方法:

要为每个入度为0的点添加入边,为每个出度为0的点添加出边

假定有 n 个入度为0的点,m个出度为0的点,如何加边?

把所有入度为0的点编号 0,1,2,3,4 ....N -1

每次为一个编号为i的入度0点可达的出度0点,添加一条出边,连到编号为(i+1)%N 的那个出度0点,

这需要加n条边

若 m <= n,则

加了这n条边后,已经没有入度0点,则问题解决,一共加了n条边

若 m > n,则还有m-n个入度0点,则从这些点以外任取一点,和这些点都连上边,即可,这还需加m-n条边。

所以,max(m,n)就是第二个问题的解

此外:当只有一个强连通分支的时候,就是缩点后只有一个点,虽然入度出度为0的都有一个,但是实际上不需要增加清单的项了,所以答案是1,0;

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <cstring>
#include <stack>
using namespace std;
#define INF 0xfffffff
#define N 10060
int Out[N],In[N], n; int low[N], dfn[N], num, cnt, Time, vis[N], belong[N];
vector<int> G[N];
stack<int>sta; void Init()
{
Time=num=cnt=;
for(int i=;i<=n;i++)
G[i].clear();
memset(dfn, , sizeof(dfn));
memset(low, , sizeof(low));
memset(vis, , sizeof(vis));
memset(belong, , sizeof(belong));
memset(Out, , sizeof(Out));
memset(In, , sizeof(In));
} void Tarjan(int u)
{
dfn[u] = low[u] = ++Time;
int len = G[u].size(), v;
sta.push(u);
vis[u] = ;
for(int i=; i<len; i++)
{
v = G[u][i];
if(dfn[v]==)
{
Tarjan(v);
low[u] = min(low[u], low[v]);
}
else if(vis[v]==)
{
low[u] = min(dfn[v], low[u]);
}
}
if(low[u]==dfn[u])
{
++num;
do
{
v = sta.top();
belong[v] = num;// 缩点;
sta.pop();
vis[v] = ;
}while(u!=v);
}
}
int main()
{
int a, ans1, ans2, ans, u, v;
while(scanf("%d", &n)!=EOF)
{
Init(); for(int i=; i<=n; i++)
{
while(scanf("%d", &a), a)
{
G[i].push_back(a);
}
}
for(int i=; i<=n; i++)
if(!dfn[i])
Tarjan(i);
ans1 = ans2 = ;
for(int i=; i<=n; i++)
{
int len=G[i].size();
for(int j=; j<len; j++)
{
u = belong[i]; v = belong[G[i][j]];
if(u!=v)
{
Out[u]++;
In[v]++;
}
}
}
for(int i=; i<=num; i++)
{
if(Out[i]==)ans2++;
if(In[i]==)ans1++;
}
ans = max(ans1, ans2);
if(num==)
printf("1\n0\n");
else
printf("%d\n%d\n", ans1, ans);
}
return ;
}
05-11 22:14