无向图中三角形个数
来源:互联网 发布:51单片机at指令 编辑:程序博客网 时间:2024/06/06 02:07
给定一个无向图,求出此图中包含三角形的个数。 图中三角形指的是:在图中任意选择三个顶点,且这三个顶点之间任意两个点都有一条来自原图中的边。求出图中三角形个数有许多应用(1)在qq中两个好友之间的共同好友个数(2)好友推荐应用。(3)图的聚集系数。(4)小世界网络。本文中所给出的算法思想: 1.对图中的所有顶点按照度数由小到大进行排序。 2.计算图中每个顶点的A[v]集合。A[v]满足(1)集合中的元素是v的邻接点(2)排名在顶点v之后。此步骤可以保证每个三角形只被计算一次。 3.对图中每条边(u,v)进行遍历,每访问一条边(u,v),求出A[v]和A[u]的交集。累计每条边的交集个数。最后交集的个数即图中三角形的个数。如下图所示: (1)顶点按照度数由小到大进行排序{2,0,4,3,1}。 (2)求出每个顶点的A[v]集合。A[0]={1,3}、A[1]={}、A[2]={1}、A[3]={1}以及A[4]={1,3}。 (3)求出每条边(u,v)中A[u]和A[v]的交集中元素的个数:(A[0],A[3])=1和(A[4],A[3])=1。
#include<iostream>#include<vector>#include<fstream>#include<algorithm>#include<time.h>using namespace std;void nodeIndegreeSort();//邻接点按照Id编号升序排序int intersect(vector<int> &v1, vector<int> &v2);//求v1和v2交集的个vector<vector<int>> mGraph;//图的存储结构vector<vector<int>> ve;//存储A[v]集合vector<int> degree;//图中节点的度int nodeNum;//图中节点的数目int edgeNum;//图中边的数目//读取图文件void readText(){ifstream fin;//fin.open("e:\\myData\\data13.txt");//读取文件//fin.open("e:\\myData\\citeseer.txt");//读取文件fin.open("e:\\myData\\cit-Patents.txt");//读取文件fin>>nodeNum>>edgeNum;mGraph.resize(nodeNum);degree.resize(nodeNum);ve.resize(nodeNum);int num1, num2, node;for(int i = 0; i < nodeNum; ++i){fin >> num1 >> num2;degree[i] += num2;for(int j = 0; j < num2; ++j){fin >> node;mGraph[i].push_back(node);mGraph[node].push_back(i);degree[node]++;}}fin.close();nodeIndegreeSort();for(int i = 0; i < nodeNum; ++i){ve[i].resize(degree[i]);}}void nodeIndegreeSort(){for(int i = 0; i < nodeNum; ++i){sort(mGraph[i].begin(),mGraph[i].end());}}//计算每个A[v]集合void rankByDegree(){for(int i = 0; i < nodeNum; ++i){int count = mGraph[i].size();int num = 0;for(int j = 0; j < count; j++){if(degree[i] < degree[mGraph[i][j]] || (degree[i] == degree[mGraph[i][j]] && i < mGraph[i][j])){ve[i][num++] = mGraph[i][j];}}ve[i].resize(num);}}//求交集int intersect(vector<int> &v1, vector<int> &v2){int num = 0;int count1 = v1.size();int count2 = v2.size();int i = 0;int j = 0;while(i < count1 && j < count2){if(v1[i] < v2[j]){i++;}else if(v1[i] > v2[j]){j++;}else{j++;i++;num++;}}return num;}//计算三角形个数int counting(){int sum = 0;for(int i = 0; i < nodeNum; ++i){int count = ve[i].size();for(int j = 0; j < count; ++j){sum += intersect(ve[i],ve[ve[i][j]]);}}return sum;}int main(void){readText();clock_t start,end;start = clock();rankByDegree();cout<<counting()<<endl;end = clock();cout<<"时间:"<<float(end - start)/CLOCKS_PER_SEC*1000<<endl;system("pause");return 0;}数据集cit-Patents
三角形个数:7515023
时间:6272ms
算法分析:(1)我们没有对顶点按照度数由小到大进行排序,而是计算出每个顶点的度数。当求A[v]时,我们只需要比较这两个顶点度数大小以及他们之间的ID编号大小即可。(2)求交集时,A[v]集合中元素按照ID编号进行排序的,我们只需遍历一次两个集合就可以得到两个集合的交集。
0 0
- 无向图中三角形个数
- 无向连通图的生成树个数
- 快速计算一个无向图中的环的个数
- 无向连通图的生成树个数
- 无向连通图的生成树个数
- 无向图求连通块的个数问题
- 求无向图中的三元环个数
- 关于求无向图的连通分量的个数
- 求简单无向图中环的个数
- 无向图割点(割点后求连通分量个数)
- 无向图中判断存在回路
- 找出平面上的特殊无向图中的所有三角形的算法
- java版无向图的深度优先搜索,求连通图个数
- hdu 4035 Lightning(无向图生成树的个数)
- HDU 4305 无向连通图的生成树个数 矩阵行列式取模
- Uva 315 求无向图的割点的个数
- 【Tinsen】A1493. 城市规划【简单无向连通图个数——NTT】
- Number of Connected Components in an Undirected Graph 无向图中的连通区域的个数
- 例题5-6 UVA 540 Team Queue团体队列
- Leetcode204: N-Queens II
- 蓝桥杯 数字三角形 Java代码
- 简单地响应式布局----CSS3中的Media Query(媒介查询)
- 数据结构基础(C语言版)(朱仲涛翻译)代码学习 第一章002
- 无向图中三角形个数
- JavaEE应用的分层模型
- poj2771——二分最大独立集
- 203. Remove Linked List Elements
- NOIP2014 Day1T1生活大爆炸版石头剪刀布 模拟
- activity,view,window,windowmanager代码阅览总结及相互关系
- Android用surface直接显示yuv数据
- 植物大战僵尸经典开发步骤
- 玩转位运算