题意:给出一个有向图,并且给出从X->Y之间的权值(也是cost),要求出强连通分量之间的最小边权,最后将求出的强连通分量之间的权值相加。

Kosaraju算法:
算法思路:
步骤1:对正向图(原图)进行dfs求解得到正向图中各节点的拓扑序并且存在数组vs中。
步骤2:得到拓扑序之后,对反向图按照逆拓扑序进行rdfs,每次rdfs都得到一个强连通分量。
注意:在进行第一步的dfs之后,将数组vis清空。

注解:Map数组记录正向图,rMap数组记录反向图,flag数组标记属于哪个连通分量,vis数组标记访问情况,vs数组记录拓扑序。

方法一:Kosaraju
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
const int maxx=50005;
const int inf=0x3f3f3f3f;
vector<int>Map[maxx],rMap[maxx],vs;
int vis[maxx];
int n,m;
int flag[maxx];
int ans[maxx];
int k;
struct node{int v,u;int cost;node(){}node(int v,int cost):v(v),cost(cost){}
};
vector<node>e[maxx];
void init(){memset(vis,0,sizeof(vis));memset(flag,0,sizeof(flag));memset(ans,inf,sizeof(ans));for(int i=0;i<=n;i++){rMap[i].clear();Map[i].clear();e[i].clear();}vs.clear();
}
void dfs(int v){vis[v]=1;for(int i=0;i<Map[v].size();i++){int t=Map[v][i];if(vis[t]==0){dfs(t);}}vs.push_back(v);
}
void rdfs(int v,int k){vis[v]=1;flag[v]=k;//代表属于k这个连通分量 for(int i=0;i<rMap[v].size();i++){int t=rMap[v][i];if(vis[t]==0){rdfs(t,k);}}
}
void solve(){for(int i=0;i<n;i++){if(vis[i]==0){dfs(i);}}memset(vis,0,sizeof(vis));k=0;for(int i=vs.size()-1;i>=0;i--){if(vis[vs[i]]==0){rdfs(vs[i],k++);}}
}
int main(){while(scanf("%d %d",&n,&m)!=EOF){if(n==0&&m==0)break;init();for(int i=1;i<=m;i++){int a,b;int cost;scanf("%d %d %d",&a,&b,&cost);e[a].push_back(node(b,cost));Map[a].push_back(b);rMap[b].push_back(a);}solve();for(int i=0;i<n;i++){for(int j=0;j<Map[i].size();j++){int t=e[i][j].v;if(flag[i]!=flag[t]){ans[flag[t]]=min(ans[flag[t]],e[i][j].cost);}}}int Min=0;for(int i=0;i<k;i++){if(ans[i]!=inf){Min+=ans[i];}}cout<<Min<<endl;}return 0;
}
方法二:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<stack>
using namespace std;
const int maxx=50005;
const int inf=0x3f3f3f3f;
vector<int>Map[maxx];
int vis[maxx];
int n,m;
int dfn[maxx];
int low[maxx];
int flag[maxx];
int ans;
int k;
struct node{int v,u;int cost;node(){}node(int v,int cost):v(v),cost(cost){}
};
vector<node>e[maxx];
stack<int>s;
int index;
void init(){index=0;ans=0;memset(vis,0,sizeof(vis));memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(flag,0,sizeof(flag));for(int i=0;i<=n;i++){Map[i].clear();e[i].clear();}
}
void dfs(int u){index++;low[u]=dfn[u]=index;s.push(u);vis[u]=1;for(int i=0;i<Map[u].size();i++){int v=e[u][i].v;if(dfn[v]==0){dfs(v);low[u]=min(low[u],low[v]);}else if(vis[v]==1){low[u]=min(low[u],dfn[v]);}}if(dfn[u]==low[u]){int v;ans++;do{v=s.top();s.pop();vis[v]=0;flag[v]=ans;}while(u!=v);}
}
int main(){while(scanf("%d %d",&n,&m)!=EOF){if(n==0&&m==0)break;init();for(int i=1;i<=m;i++){int a,b;int cost;scanf("%d %d %d",&a,&b,&cost);e[a].push_back(node(b,cost));Map[a].push_back(b);}for(int i=0;i<n;i++){if(dfn[i]==0){dfs(i);}}int dist[maxx];for(int i=0;i<=n;i++){dist[i]=inf;}for(int i=0;i<n;i++){for(int j=0;j<Map[i].size();j++){int t=e[i][j].v;if(flag[i]!=flag[t]){dist[flag[t]]=min(dist[flag[t]],e[i][j].cost);}}}int Min=0;for(int i=0;i<ans;i++){if(dist[i]!=inf){Min+=dist[i];}}cout<<Min<<endl;}return 0;
}

HDU3072(Kosaraju算法)相关推荐

  1. HDU4635(强连通分量+Kosaraju算法)

    题意:给出一个有向图,最多添加多少条边使这个图依然不是强连通图:当这个图是强连通图时,输出-1: 求解思路:强连通分量求解: 强连通图:在有向图中,任意节点除法都可以到达其余所有节点,则称为强连通图. ...

  2. HDU2767(强连通分量+Kosaraju算法)

    题意:需要加多少边才能把一个图变成强连通分量 强连通图:在有向图中,任意节点除法都可以到达其余所有节点,则称为强连通图. 强连通分量:在非强连通图的有向图中,选取部分点为强连通图,该强连通子图称为强连 ...

  3. kosaraju算法

    kosaraju算法用来求有向图的强连通分量 文章目录 我们需要提前知道的知识 什么是强连通 强连通分量 无向图的连通分量怎么计算 什么是顶点的逆后序排列 什么是反向图 kosaraju算法 对于该算 ...

  4. Kosaraju 算法检测有向图的强连通性

    给定一个有向图 G = (V, E) ,对于任意一对顶点 u 和 v,有 u --> v 和 v --> u,亦即,顶点 u 和 v 是互相可达的,则说明该图 G 是强连通的(Strong ...

  5. Kosaraju 算法查找强连通分支

    有向图 G = (V, E) 的一个强连通分支(SCC:Strongly Connected Components)是一个最大的顶点集合 C,C 是 V 的子集,对于 C 中的每一对顶点 u 和 v, ...

  6. Kosaraju算法、Tarjan算法分析及证明--强连通分量的线性算法

    一.背景介绍 强连通分量是有向图中的一个子图,在该子图中,所有的节点都可以沿着某条路径访问其他节点.强连通性是一种非常重要的等价抽象,因为它满足 自反性:顶点V和它本身是强连通的 对称性:如果顶点V和 ...

  7. Kosaraju算法(发现强连通分图算法)

    看论文的时候,看到Kosaraju算法.Kosaraju是一个强连通分图的发现算法,如有代码中有详细的注释,所以就不赘述了.直接上码(使用webgraph库实现,在我之前的文章中,对webgraph有 ...

  8. 有向图最长路径算法_算法数据结构 | 三个步骤完成强连通分量分解的Kosaraju算法...

    强连通分量分解的Kosaraju算法 今天是算法数据结构专题的第35篇文章,我们来聊聊图论当中的强连通分量分解的Tarjan算法. Kosaraju算法一看这个名字很奇怪就可以猜到它也是一个根据人名起 ...

  9. 图论 —— 图的连通性 —— Kosaraju 算法

    [概述] Kosaraju 算法是最容易理解,最通用的求强连通分量的算法,其关键的部分是同时应用了原图 G 和反图 GT . [基本思想] 1.对原图 G 进行 DFS 搜索,计算出各顶点完成搜索的时 ...

最新文章

  1. 边缘计算不再“边缘”
  2. 苏勇老师写的CCIE详解
  3. 使用Poco实现插件方式加载动态库
  4. “个人核心竞争力”与“危机感”
  5. ROC和AUC介绍以及如何计算AUC(转载+自己重新排版整理)
  6. linux的/etc/passwd、/etc/shadow、/etc/group和/etc/gshadow
  7. Find the Kth number(找第K大数)
  8. 疲劳驾驶样本集_欧洲要求,2022年开始新车必须配备DMS(防疲劳预警)系统
  9. JasperReport报表导出PDF中文不显示的问题
  10. [转]HTTP 错误 403.1 - 禁止访问:执行访问被拒绝。
  11. php异步表单,利用ajax实现表单的异步互动——2018年4月10日
  12. java实现netstat命令功能_netstat命令 详解
  13. VS2005精简版(二)
  14. 分享一份接口测试项目(非常值得练手)
  15. 操作系统server 2012 r2 安装简体中文语言包
  16. 超出ipc连接数范围_终端服务器超出了最大允许连接数的解决办法 (全文)
  17. FTRL之FM和LR实战(使用稀疏数据进行实战)
  18. 人脸识别活体检测技术探讨:多物理特征融合加分类器的算法技术
  19. 杭州电子科技大学计算机学院院长,杭州电子科技大学计算机学院导师教师师资介绍简介-彭勇...
  20. 2021年剑桥高考成绩查询,2021年剑桥五级KET、PET、FCE成绩查询指南

热门文章

  1. python 示列:抓取网页所有a连接
  2. python使用PyMySQL的连接MySQL数据库
  3. 数据结构-图-遍历-搜索
  4. C语言字符串一道比较难的题!_只愿与一人十指紧扣_新浪博客
  5. 多摄像头实时目标跟踪和计数,使用YOLOv4,Deep SORT和Flask
  6. 网站优化基础教程:发布外链常见的五种方式!
  7. 网页制作-表单元素2
  8. php中instanceof的使用
  9. 还不错的Table样式和form表单样式
  10. ORACLE 12C PDB部分功能测试