POJ1236 Network of Schools【Tarjan】【强连通分量】
来源:互联网 发布:世界导航软件 编辑:程序博客网 时间:2024/05/21 17:53
题目链接:
http://poj.org/problem?id=1236
题目大意:
N台电脑之间能够通过有向边(u,v)从第u台电脑传输文件到第v台电脑。如果给第u台电脑投放
一个文件,那么这个文件就能通过有向边传输到第v台电脑上,给你N台电脑的连接情况。
那么问题来了:1、最少向这N台电脑中的几台电脑投放文件,就能使N台电脑都能接收到文件。
2、最少向这N台电脑构成的图中添加几条边,使只向一台电脑投放文件,就能够是N台电脑都
能接收到文件。
思路:
该图中的文件具有传递性。很快发现强连通的特征。对应图中的一个强连通分量,只要向其中的
一个点投放文件,那么这个强连通分量就都能收到文件。将这个强连通分量缩点变为DAG(有向
无环图)。这是解第一个问题的基础。
在有向无环图中,边变为了强连通分量之间的文件传输关系。意味这:只要一个强连通分量有入
边,那么就可以通过这个入边从另外一个分量中接收文件。但是,无环图意味着肯定存在没有入
度(入度为0)的强连通分量,这些强连通分量没有文件来源,所以要作为投放文件的位置。那么,
第一问就只需要计算出缩点后入度为0的强连通分量数目即可。
而第二个问题,把一个有向无环图转换为一个强连通分量。强连通分量的主要特征是:每个点的
入度和出度都不为0,那么计算出入度为0的点的个数SumIn和出度为0的点的个数SumOut,题
目就变为了:在入度为0的点和出出度为0的点之间最少加多少边。很明显的可以看出,答案就是
max(SumIn,SumOut)。
AC代码:
#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>using namespace std;const int MAXN = 110;const int MAXM = 10100;struct EdgeNode{ int to; int next;}Edges[MAXM];int Head[MAXN],vis[MAXN],low[MAXN];int dfn[MAXN],Stack[MAXN],indegree[MAXN],outdegree[MAXN];int Count[MAXN],m,id;void AddEdges(int u,int v){ Edges[id].to = v; Edges[id].next = Head[u]; Head[u] = id++;}int TarBFS(int pos,int lay,int &scc){ vis[pos] = 1; low[pos] = dfn[pos] = lay; Stack[++m] = pos; for(int i = Head[pos]; i != -1; i = Edges[i].next) { if(!vis[Edges[i].to]) TarBFS(Edges[i].to,++lay,scc); if(vis[Edges[i].to] == 1) low[pos] = min(low[pos],low[Edges[i].to]); } if(dfn[pos] == low[pos]) { ++scc; do { Count[scc]++; low[Stack[m]] = scc; vis[Stack[m]] = 2; }while(Stack[m--] != pos); } return 0;}void Tarjan(int N){ int scc, temp, lay; scc = temp = m = 0; lay = 1; memset(vis,0,sizeof(vis)); memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); for(int i = 1; i <= N; ++i) if(vis[i] == 0) TarBFS(i,lay,scc); for(int i = 1; i <= N; ++i) { for(int j = Head[i]; j != -1; j = Edges[j].next) if(low[i] != low[Edges[j].to]) { outdegree[low[i]]++; indegree[low[Edges[j].to]]++; } } int SumIn = 0, SumOut = 0; for(int i = 1; i <= scc; ++i) { if(!indegree[i]) SumIn++; if(!outdegree[i]) SumOut++; } if(scc == 1) printf("1\n0\n"); else printf("%d\n%d\n", SumIn, max(SumIn,SumOut));}int main(){ int N, v; while(~scanf("%d", &N)) { memset(Head,-1,sizeof(Head)); memset(outdegree,0,sizeof(outdegree)); memset(indegree,0,sizeof(indegree)); memset(Count,0,sizeof(Count)); id = 0; for(int i = 1; i <= N; ++i) while(scanf("%d",&v) && v) AddEdges(i,v); Tarjan(N); } return 0;}
0 0
- POJ1236 Network of Schools【Tarjan】【强连通分量】
- POJ1236 Network of Schools(强连通分量:Tarjan算法)
- poj1236 Network of Schools 【连通图-强联通分量-tarjan】
- poj1236 Network of Schools(强连通分量,tarjan)
- poj1236-network of schools(强连通分量)
- poj1236 Network of Schools 强连通分量
- POJ1236 Network of Schools 【强连通分量】
- [POJ1236]Network of Schools(Tarjan缩点+强连通分量)
- POJ1236---Network of Schools (强连通分量,缩点,Tarjan算法)
- Network of Schools POJ1236(tarjan缩点+强连通分量模板)
- 【强连通分量】Tarjan(缩点)POJ1236-Network of Schools
- POJ1236 Network of Schools 【强连通分量Garbow】
- POJ1236 Network of Schools(缩点+结论+强连通分量)
- poj 1236 Network of Schools(强连通分量 Tarjan)
- poj 1236 Network of Schools(强连通分量 Tarjan算法)
- POJ-1236 Network of Schools (强连通分量[Tarjan])
- POJ 1236 Network of Schools (强连通分量tarjan)
- POJ1236:Network of Schools(强连通)
- 浅谈C#中的#region指令
- 中印救命药差价百倍原因:中国仿制药申报周期太长
- 24.字符串的排列
- Android(Java)正则表达式判断手机号、邮箱、身份证号码、密码、Url、邮编等工具类
- tar 解压缩命令
- POJ1236 Network of Schools【Tarjan】【强连通分量】
- 自由了吗 ——读《自由》
- 复选框应用
- android 获取界面上所有控件
- 错误隐藏学习手记(六)
- android update-binary
- ubuntu ssh
- 1.CSS的命名
- PostgreSql创建数据库