最小圈基问题
来源:互联网 发布:搜索下载 python 实现 编辑:程序博客网 时间:2024/04/29 23:41
算法分析实验,写的有点乱,保存备用,同时供大家参考,写的不是很好,如有问题可提出交流和修改!
#include<iostream>#include<vector>#include<set>using namespace std;static int temp = 0;//在找圈方法中用于圈个数的计数class Circle{public:Circle(){this->vertexNum = 0;this->circleWeight = 0;vertex = new pair<int, int>[10];circleEdge.resize(10);}int getCircleWeight() //计算并返回圈的权{for (int i = 0; i < vertexNum; i++){circleWeight += circleEdge[i];}return circleWeight;}public:int vertexNum; //圈的顶点数vector<int> circleEdge; //二维数组存储边的权int circleWeight; //圈的权值pair<int, int> *vertex; //存储圈的边的坐标};class MatrixGraphic{public:MatrixGraphic(){this->vertexNum = 0;this->edgeNum = 0;this->graphicWeight = 0;this->circleNum = 0;}MatrixGraphic(int verNumber, int edgNumber){circle = new Circle[10];vector<vector<int>> a(verNumber);this->vertexNum = verNumber;this->edgeNum = edgNumber;mixCircleNum = (edgeNum + 1) - vertexNum;edge = a;for (int i = 0; i <vertexNum; i++)edge[i].resize(vertexNum); //初始化邻接矩阵的大小}/*输入整个图*/void cinGraphic();/*找出所有圈并对其按照权的大小进行升序排序*/void fundCircle(int num1, int num2,int num3,vector<pair<int,int> > b);/*是否能组成圈*/bool isCircle(int num,vector<pair<int, int> > b);/*找最小圈基*/int fundMinCircle();/*判断一个圈是否是圈基中的线性组合*///void isCombin(int n);/*是否停止向圈基中继续加圈*///bool isStop(int n);public:int vertexNum; //图的顶点数int edgeNum; //图的边数int graphicWeight; //图的权值vector<vector<int>> edge; //二维数组存储边的权pair<int,int> vertex[20]; //存储边的坐标Circle* circle; //图中各圈int circleNum; //计数器,计算圈的个数int mixCircleNum; //最小圈基的范围};void MatrixGraphic::cinGraphic(){int num = 0;cout << "请以"<< vertexNum <<"*"<< vertexNum <<"的邻接矩阵的形式输入图:" << endl;for (int i = 0; i < vertexNum; i++)for (int j = 0; j < vertexNum; j++){int n;cin >> n;edge[i][j] = n;}/*存储图的边的坐标*/for (int i = 0; i < vertexNum; i++)for (int j = i; j < vertexNum; j++){if (edge[i][j] != 0){vertex[num].first = i;vertex[num].second = j;num++;}}}/*用组合算法找出n个顶点的所有组合(不考虑位置) num1为图的顶点个数,num2为组合的顶点个数,b为所有组合构成的集合*/void MatrixGraphic::fundCircle(int num1, int num2,int num3, vector<pair<int,int> > b){for (int i = num1; i >= num2; i--) {/*找出组合*/b[num2 - 1] = vertex[i - 1];if (num2 > 1){fundCircle(i - 1, num2 - 1, num3, b);}else {/*如果组合能构成圈,将其放到circle中*/if (isCircle(num3, b)) {for (int i = b.size() - 1; i >= 0; i--){circle[temp].vertex[i] = b[i]; //将顶点赋值给对应的圈的顶点circle[temp].circleEdge[i] = edge[b[i].first][b[i].second];}circleNum += 1;circle[temp].vertexNum = b.size();++temp;}}}}/*判断是否构成圈思路:(1)n条边能组合成圈的顶点只有n个(2)所有边的坐标点的集合都是成对出现的,如(01 03 12 23中0 1 2 3都是成对出现的)(3)*/bool MatrixGraphic::isCircle(int num, vector<pair<int, int> > b){vector<int> ver;set<int>s0;set<int>s1;set<int>s2;int n = 0;for (int i = 0; i < b.size(); i++){s0.insert(b[i].first);}for (int i = 0; i < b.size(); i++){s1.insert(b[i].second);}for (int i = 0; i < b.size(); i++){ver.push_back(b[i].first);ver.push_back(b[i].second);s2.insert(b[i].first);s2.insert(b[i].second);}/*n条边能组合成圈的顶点只有n个,且都是成对出现的(有且只有两个)*/for (int i = 0; i < b.size() * 2; i++){for (int j = 0; j < b.size() * 2; j++){if (ver[i] == ver[j])n += 1;}if (n > 2)return false;else{n = 0;}}if (s2.size() == num && s0.size() == (num - 1) && s1.size() == (num - 1) )return true;elsereturn false;}/*找最小圈基的思路:对排好序的圈挨个放进圈基,如果圈是圈基的线性组合(即圈的所有边在圈基中都可以找到),删掉直到圈基中圈的个数满足要求停止加圈*/int MatrixGraphic::fundMinCircle(){static int temp1 = 2;int minCircle = 0; //最小圈基的权set<pair<int,int> >MySet;Circle *Mycircle = new Circle[mixCircleNum];for (int i = 0; i < circleNum; i++){if (i < 2){Mycircle[i] = circle[i];}else{/*先把所有的边放到集合set中*/for (int a = 0; a < i; a++){for (int b = 0; b < circle[a].vertexNum; b++){MySet.insert(Mycircle[a].vertex[b]);}}temp = 0;for (int j = 0; j < circle[i].vertexNum; j++)//检验第i是否是组合成的,分别扫描它的所有顶点{if (MySet.find(circle[i].vertex[j])!=MySet.end()){temp += 1;}}if (temp != circle[i].vertexNum){Mycircle[temp1] = circle[i];temp1++;}if (temp1 == (mixCircleNum))break;MySet.clear();}}for (int i = 0; i < mixCircleNum; i++){minCircle += Mycircle[i].circleWeight;}/*输出最小圈基*/cout <<endl<< "最小圈基:" << endl;for (int i = 0; i < mixCircleNum; i++){for (int j = 0; j < Mycircle[i].vertexNum; j++){cout << Mycircle[i].vertex[j].first << Mycircle[i].vertex[j].second << " ";}cout << endl;}return minCircle;}int main(){int e, v; //存储图的顶点和边cout << "请输入图的顶点和边数:" << endl;cin >> e >> v;MatrixGraphic MyGraphic(e,v); //定义一个图对象MyGraphic.cinGraphic(); //调用cinGraphic()方法,以邻接矩阵的形式输入整个图//找到所有的圈/*找圈的思路:(1)3个或3个以上的顶点可构成圈,找出可以构成圈的所有可能的顶点组合(2)从找出的组合中再筛选出真正能构成圈的*/for (int i = 3; i <= v; i++){vector<pair<int, int> > b(i);MyGraphic.fundCircle(v, i,i, b);//fundCircle方法用到了排列组合}cout << "输出图中所有圈的权:" << endl;for (int i = 0; i < MyGraphic.circleNum; i++){MyGraphic.circle[i].getCircleWeight(); //计算圈的权cout << MyGraphic.circle[i].circleWeight << " ";}/*对所有圈按照升序排列*/Circle MyCircl;for (int i = 0; i < MyGraphic.circleNum - 1; i++){for (int j = i+1; j < MyGraphic.circleNum ; j++)if (MyGraphic.circle[i].circleWeight > MyGraphic.circle[j].circleWeight){MyCircl = MyGraphic.circle[i];MyGraphic.circle[i] = MyGraphic.circle[j];MyGraphic.circle[j] = MyCircl;}}cout << endl;cout << "排序后的圈的权:" << endl;for (int i = 0; i < MyGraphic.circleNum; i++){//MyGraphic.circle[i].getCircleWeight();cout << MyGraphic.circle[i].circleWeight << " ";}cout<<endl<<"最小圈基的权:"<<MyGraphic.fundMinCircle()<<endl;//调用fundMinCircle()方法,输出最小圈基和它的权return 0;}
0 0
- 最小圈基问题
- 分治法:最小套圈问题【分析】
- 最小套圈问题双重循环算法
- 分治法解决最小套圈问题
- 最小圈
- HNOI2009 最小圈
- BZOJ 1486 最小圈
- [bzoj1486][HNOI2009]最小圈
- bzoj1486【HNOI2009】最小圈
- bzoj1486 [HNOI2009]最小圈
- BZOJ1486: [HNOI2009]最小圈
- 1486: [HNOI2009]最小圈
- bzoj1486: [HNOI2009]最小圈
- 【BZOJ 1486】 [HNOI2009]最小圈
- 【bzoj1486】最小圈 分数规划
- BZOJ 1486: [HNOI2009]最小圈
- [BZOJ 1486][HNOI2009]最小圈
- BZOJ 1486: [HNOI2009]最小圈
- 【java算法】二叉树遍历、求叶子数--用递归的方法
- CC2541 AirSync(5)——登录包
- 笔记
- Java 中String对象比较方法equals和等号==
- CoordinatorLayout 、FloatingActionButton 、Snackbar、DrawerLayout和NavigationView结合使用demo
- 最小圈基问题
- Method Swizzling、AOP 面向切片编程
- Hibernate缓存
- 一个伟大的发现,装X一下。笔记本win7系统64位机器运行unity 时,屏幕模糊解决办法
- python中的闭包
- 数据结构上机实验(二)
- Android APP性能优化十大方案
- linux目录作用详解(超详细,树状排版)
- MapReduce实现TopK