poj 1236
来源:互联网 发布:centos png 编辑:程序博客网 时间:2024/06/05 09:53
这个题目有点难懂 , (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];
}
elseif(!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;
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()
{