这个题目有点难懂 , (Subtask A)和(Subtask B)是表示两个任务 , 就是两个问题 。
A:求出最少给几个点发送软件 , 才能让所有点都能得到这个软件。
B:在建成的图中 , 最少要增加几条边 ,才能让其变成一个强连通图 。
解法:
A:先求出所有强连通分量 , 然后再用这些分量去建一个图 , 图中入度为0的点 , 就是要发送软件的点 。
代码:
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 200 ;
vectorgrap[MAXN] , scc[MAXN];
int pre[MAXN] , lowlink[MAXN] , sccno[MAXN];
int n , dfs_clock , scc_cnt;
stacks;
void init()
{
for(int i = 1 ; i <= n; i++)
{
grap[i].clear();
scc[i].clear();
}
}
void dfs(int u) // 寻找强连通分量
{
lowlink[u] = pre[u] = ++dfs_clock;
s.push(u);
for(int i = 0 ; i < grap[u].size() ; i++)
{
int v = grap[u][i];
if(!pre[v])
{
dfs(v);
if(lowlink[u] > lowlink[v])
lowlink[u] = lowlink[v];
}
else if(!sccno[v] && lowlink[u] > pre[v])
lowlink[u] = pre[v];
}
if(lowlink[u] == pre[u])
{
scc_cnt++;
for(; ;)
{
int x = s.top() ; s.pop();
sccno[x] = scc_cnt;
if(x == u)
break;
}
}
}
void find_scc()
{
memset(pre, 0 , sizeof(pre));
memset(sccno , 0 , sizeof(sccno));
dfs_clock = scc_cnt = 0;
for(int i = 1; i <= n; i++)
if(!pre[i])
dfs(i);
}
int main()
{
while(scanf("%d" , &n ) != EOF)
{
init();
int i , x , y , j;
for(i = 1 ; i <= n; i++)
{
for(; ; )
{
scanf("%d" , &x);
if(x == 0)
break;
grap[i].push_back(x);
}
}
find_scc();
int chu_du[MAXN] , ru_du[MAXN];
memset(chu_du , 0 , sizeof(chu_du) );
memset(ru_du , 0 , sizeof(ru_du));
for(i = 1; i <= n; i++)
for(j = 0 ; j < grap[i].size();
j++)
{
int v = grap[i][j];
x = sccno[i] ;
y = sccno[v];
if(x != y)
{
scc[x].push_back(y);
ru_du[y]++;
chu_du[x]++;
}
}
x = 0 , y = 0;
for(i = 1; i <= scc_cnt ; i++)
{
if(!chu_du[i])
x += 1;
if(!ru_du[i])
y += 1;
}
x = x>y?x:y;
if(scc_cnt == 1) {y = 1; x = 0;}
printf("%d\n" , y);
printf("%d\n" , x);
}
return 0;
}
A:求出最少给几个点发送软件 , 才能让所有点都能得到这个软件。
B:在建成的图中 , 最少要增加几条边 ,才能让其变成一个强连通图 。
解法:
A:先求出所有强连通分量 , 然后再用这些分量去建一个图 , 图中入度为0的点 , 就是要发送软件的点 。
代码:
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 200 ;
vectorgrap[MAXN] , scc[MAXN];
int pre[MAXN] , lowlink[MAXN] , sccno[MAXN];
int n , dfs_clock , scc_cnt;
stacks;
void init()
{
}
void dfs(int u)
{
}
void find_scc()
{
}
int main()
{
}