数据结构三级项目c++代码,基于有向有权图的信息管理系统


数据结构三级项目,有向有权图的应用。

整体架构

项目设计7个类(图一),另外还有一个基础的graph类,这些类中最主要的就是arrayWDgraph这个类了,其他的类都是为它服务的,关于图的功能和操作也都是在arrayWDgraph这个类里。arrayWDgraph继承了抽象类graph,并且实现了graph中的方法,同时做出了一定的扩展,编写了其他的方法。
类视图

类对应的实际问题

实际问题的描述

项目所对应的实际问题是军事信息整合与处理,具体到项目里就是对军事中地点占领,路线,队伍的安排。计划解决两个主要的问题,就是队伍的顺序安排以及地点间最短路径的计算。队伍顺序的安排就是对队伍上前线的顺序的安排,对于军队来说上战场时的队伍是有一定的顺序安排的,前面的队伍为后面的队伍做好铺垫,后面的队伍就可以迅速地投入战场,取得宝贵的时机。另一个就是对地点间的最短路径的计算,战场上需要在不同的地点作战,所以地点间的转移的路线一定要是最短的才可以,这样就可以迅速地抵达目的地。

实际问题在类中的体现

node类代表的是图中的点,edge类代表的是图中的边,vertexIterator类代表的是迭代器,work代表的是队伍,nodefrom是点的另一种表示,works代表的是队伍系统,graph是基类,而arrayWDgraph是继承基类的代表有向有权图的类。
(1)类的实现中,node类所带有的信息仅仅是点的编号和边的权值,这样一个点会存在边所对应的邻接数组中,用来表示边。node类的方法也只有获取编号和获取权值。
(2)nodefrom类带有的信息包括点的编号,名字,入度,出度,以及占领情况。nodefrom类中除了构造函数没有别的方法。仅作为一个点的抽象。
(3)edge类表示的是边,带有的信息有边的起点和终点还有边的权值,含有的方法是返回起点、返回终点、返回权值,以及输出边的信息。
(4)vertexIterator类在定义的时候作为抽象类被定义,之后在后面被继承实现里面的方法,方法就是将游标移到下一位。
(5)work类仅作为队伍的抽象保存队伍的编号,名字,入度,出度。work类中只有构造函数一个方法。
(6)works类表示的是队伍安排系统,主要的功能就是对队伍的顺序的安排,用到的算法是拓扑排序,里面的队伍用到的数据结构也是邻接数组,来表示队伍之间的先后顺序。该类中也有其他的基础方法,包括加点,删点,加边,删边,以及嵌在它们中的一些小方法。
(7)arrayWDgraph类是最重要的类,其他的类都被它调用。作为有向有权图的类,它带有的信息包括有顶点数、边数、边对应的邻接数组、点对应的栈。它里面的方法大致分为四种,第一种基于图的能够被别的方法调用的基础方法,用来获取点或边的一些信息。包括有获取编号为x的点的索引,获取点的个数、获取边的个数、判断是否存在点x、判断是否存在边(a,b)、判断点x是否合法、判断边(a,b)是否合法、判断占领值是否合法、获取入度、获取出度、获取度、是否为有向图、是否为有权图、获取文件中第一部分字符串、获取文件中第二部分字符串、获取文件中第三部分字符串、获取点的占领情况。第二种是对图修改的方法,包括有增加点、删除点、增加边、删除边、更新权值、更新占领值、100个点初始化、5个点初始化、清空图。第三种是算法相关的方法有拓扑排序、佛洛依德算法、深度优先算法。第四种是方便用户互动的方法,为其他算法服务,有打印路线、删除点和边、增加点和边等方面的引导的方法。

graph.h

#ifndef graph_
#define graph_
#include"edge.h"
#include"vertexIterator.h"
template<class T>
class graph
{
    
    
public:
    virtual ~graph() {
    
    }
    virtual int numberOfVertices() const = 0;//点的个数
   virtual int numberOfEdges() const = 0;//边的个数
    virtual bool existsEdge(int, int) const = 0;//判断是否存在从前面点到后面点的边
    virtual void insertEdge(edge<T>*) = 0;//插入边
    virtual bool eraseEdge(int, int) = 0;//删除边
    virtual int degree(int) const = 0;//度
    virtual int indegree(int) const = 0;//入度
    virtual int outdegree(int) const = 0;//出度
    virtual bool directed() const = 0;//方向
    virtual bool weighted() const = 0;//权重
    virtual vertexIterator<T>* iterator(int) = 0;//迭代器
};
#endif

edge.h

#pragma once
#ifndef edge_
#define edge_
#include<iostream>
using namespace std;
template<class T>
class edge {
    
    
public:
	edge(int x=-1,int y=-1,T we=0) {
    
    
		v1 = x;
		v2 = y;
		w = we;
	}
	~edge() {
    
    }
	int getS1() {
    
    
		return v1;//返回点1
	}
	int getS2() {
    
    
		return v2;//返回点2
	}
	T getW() {
    
    
		return w;//返回权值
	}
	void output() {
    
    
		cout << "(" << v1 << "," << v2 << "," << w << ")";
	}
private:
	int v1;//点1
	int v2;//点2
	T w;//权值
};
#endif

node.h

#pragma once
#ifndef  node_
#define node_

#include<iostream>
using namespace std;
template<class T>
class node {
    
    
public:
	int number;//该点的编号
	T weight;//权值
	node(int num,int we=0) {
    
    
		number = num;
		weight = we;
	}
	int getn() {
    
    
		return number;
	}
	int getw() {
    
    
		return weight;
	}
	bool operator==(int y) {
    
    
		if (y == this->number)return true;
		else return false;
	}
};

class nodeform {
    
    
public:
    int ver;
	int occupy;//用来判断该点是否已经占领
	int indegree;//该点的入度
	int outdegree;//该点的出度
	string name;//该点所代表的地区的名字
	nodeform(int oc = 0,int ve = 0, string na = "",int in = 0, int out = 0 )
	{
    
    
		occupy = oc;
		name = na;
		ver = ve;
		indegree = in;
		outdegree = out;
	}
	
};

#endif

vertexIterator.h

#pragma once

#ifndef vertexIterator_
#define vertexIterator_

using namespace std;

template<class T>
class vertexIterator
{
    
    
public:
    virtual ~vertexIterator() {
    
    }
    virtual int next() = 0;
    virtual int next(T&) = 0;
};
#endif

work.h

#pragma once
#ifndef  work_
#define work_
#include<iostream>
#include<string>
#include<vector>
#include"node.h"
#include"edge.h"
#include<stack>
#include< fstream>
#include <sstream>
using namespace std;

class work {
    
    
public:
	int ver;//队伍编号
	int indegree;//该队伍的入度
	int outdegree;//该队伍的出度
	string name;//队伍名称
	work(int ve = 0, string na = "", int in = 0, int out = 0)
	{
    
    
		name = na;
		ver = ve;
		indegree = in;
		outdegree = out;
	}
};
template<class T>
class works {
    
    
public:
	struct VE {
    
    
		int ve;
		vector<node <T>> g;
	};
	vector<VE> E;//队伍先后联系图
	vector<work> W;//队伍图
	int num, edges;//分别是队伍数和队伍先后联系数
	works(int v = 0)//构造函数
	{
    
    
		while (1)
		{
    
    
			if (v < 0)
			{
    
    
				cout << "输入不标准!请重新输入:" << endl;
				cin >> v;
			}
			else
			{
    
    
				break;
			}
		}
		num = v;
		edges = 0;
		W = vector<work>(num + 1);
		E = vector<VE>{
    
     (unsigned int)(num + 1),VE() };
	}
	~works() {
    
    }
	//获取编号为x的队伍的索引
	int reindex(int x) {
    
    
		for (int i = 1; i <= num; i++)
		{
    
    
			if (W[i].ver == x)
			{
    
    
				return i;
			}
		}
	}
	//判断联系v1->v2是否合法
	bool legaledge(int v1, int v2)
	{
    
    
		if (v1 < 1 || v2 < 1)
		{
    
    
			return false;
		}
		else
		{
    
    
			return true;
		}
	};
	//判断队伍v是否合法
	bool legalvertex(int v) {
    
    
		if (v >= 1)
		{
    
    
			return true;
		}
		else
		{
    
    
			cout << "点不合法!" << endl;
			return false;
		}
	}
	//判断是否存在联系a->b
	bool existsEdge(int a, int b) const {
    
    
		int c = E[a].g.size();
		for (int i = 0; i < c; i++)
		{
    
    
			if (E[a].g[i].number == b)
			{
    
    
				return true;
			}
		}
		return false;
	};
	//判断是否已经存在队伍v
	bool existvertex(int v)
	{
    
    
		for (int i = 0; i < W.size(); i++)
		{
    
    
			if (v == W[i].ver)
			{
    
    
				return true;
			}
		}
		return false;
	}
	//增加队伍
	void addvertex(int v, string na) {
    
    
		work node(v, na);
		W.push_back(node);
		VE nod;
		nod.ve = v;
		nod.g.clear();
		E.push_back(nod);
		num++;
	}
	//删除队伍
	void deletevertex(int v) {
    
    
		int x = reindex(v);
		int f = E[x].g.size();
		E.erase(E.begin() + x, E.begin() + x + 1);
		edges -= f;
		W.erase(W.begin() + x, W.begin() + x + 1);
		for (int i = 1; i < E.size(); i++)
		{
    
    
			for (int j = 0; j < E[i].g.size(); j++)
			{
    
    
				if (E[i].g[j].number == v)
				{
    
    
					E[i].g.erase(E[i].g.begin() + j, E[i].g.begin() + j + 1);
					W[i].outdegree--;
					edges--;
				}
			}
		}
		num--;
	}
	//增加联系
	void insertEdge(edge<T>* Edge) {
    
    
		int v1 = Edge->getS1();
		int v2 = Edge->getS2();
		if (!legaledge(v1, v2))
		{
    
    
			return;
		}
		int v = reindex(v1);
		if (existsEdge(reindex(v1), v2))
		{
    
    
			auto p = E[v].g.begin();
			for (int i = 0; i < E[v].g.size(); i++)
			{
    
    
				if (E[v].g[i].number == v2)
				{
    
    
					p = find(E[v].g.begin(), E[v].g.end(), v2);
				}
			}
		}
		else
		{
    
    
			W[reindex(v2)].indegree++;
			W[v].outdegree++;
			node<T> no(v2);
			E[v].g.push_back(no);
			edges++;
		}
	};
	//删除联系
	bool eraseEdge(int v1, int v2) {
    
    
		int v = reindex(v1);
		if (!legaledge(v1, v2))
		{
    
    
			return false;
		}
		if (!existsEdge(reindex(v1), v2))
		{
    
    
			return false;
		}
		for (int i = 0; i < E[v].g.size(); i++)
		{
    
    
			if (E[v].g[i].number == v2)
			{
    
    
				E[v].g.erase(remove(E[v].g.begin(), E[v].g.end(), v2), E[v].g.end());
				W[v].outdegree--;
				W[v].indegree--;
				edges--;
				break;
			}
		}
		return true;
	};
	//返回第一部分的字符串
	string first(string s) {
    
    
		string f;
		for (int i = 0; i < s.size(); i++)
		{
    
    
			if (s[i] == ' ')
			{
    
    
				f = s.substr(0, i + 1);
				break;
			}
		}
		return f;
	}
	//返回第二部分的字符串
	string second(string s) {
    
    
		string f;
		int x;
		for (int i = 0; i < s.size(); i++)
		{
    
    
			if (s[i] == ' ')
			{
    
    
				f = s.substr(i + 1, s.size() - i - 1);
			}
		}
		return f;
	}
	//返回第一个空格位置的索引
	int reoneblank(string s) {
    
    
		int x;
		for (int i = 0; i < s.size(); i++)
		{
    
    
			if (s[i] == ' ')
			{
    
    
				x = i;
				break;
			}
		}
		return x;
	}
	//在文件中写入点x
	void advf(int x, string y) {
    
    
		ofstream outfile;
		outfile.open("workv.txt", ios::app);
		outfile << x << " " << y << endl;
		outfile.close();
	}
	//添加队伍
	void adv()
	{
    
    
		system("cls");
		cout << "当前功能为添加队伍" << endl;
		int n;
		cout << "请输入添加的队伍的个数:";
		cin >> n;
		int x;
		string y;
		for (int i = 0; i < n; i++)
		{
    
    
			cout << "请输入队伍的编号:";
			while (1)
			{
    
    
				cin >> x;
				if (!legalvertex(x))
				{
    
    
					cout << "输入不规范!请重新输入:";
					continue;
				}
				else if (existvertex(x))
				{
    
    
					cout << " 该队伍已经存在!" << endl;
					cout << "请重新输入:";
					continue;
				}
				break;
			}
			cout << "请输入队伍的名字:";
			cin >> y;
			addvertex(x, y);
			advf(x, y);
			cout << "队伍" << x << "增加成功!" << endl;
			break;
		}
		int a;
		cout << "返回主页请按0 继续添加请按1" << endl;
		cin >> a;
		if (a)
		{
    
    
			adv();
		}
		else
		{
    
    
			return;
		}
	}
	//添加队伍重载函数
	void adv(int x)
	{
    
    
		string y;
		cout << "请输入队伍的名字:";
		cin >> y;
		while (1)
		{
    
    
			if (legalvertex(x))
			{
    
    
				addvertex(x, y);
				advf(x, y);
				cout << "队伍" << x << "增加成功!" << endl;
				break;
			}
			else
			{
    
    
				cout << "输入不规范,请重新输入:";
				cin >> x;
				continue;
			}
		}
	}
	//删除队伍的文件操作
	void devf(int x) {
    
    
		vector<string>vf;
		string s;
		fstream outfile;
		outfile.open("workv.txt");
		while (!outfile.eof())
		{
    
    
			getline(outfile, s);
			if (atoi(first(s).c_str()) != x && s != "")
			{
    
    
				vf.push_back(s);
			}
		}
		outfile.close();
		ofstream out("workv.txt");
		out.close();
		outfile.open("workv.txt", ios::app);
		for (int i = 0; i < vf.size(); i++)
		{
    
    
			outfile << vf[i] << endl;
		}
		outfile.close();
		vf.clear();
		outfile.open("worke.txt");
		while (!outfile.eof())
		{
    
    
			getline(outfile, s);
			if (s != "")
			{
    
    
				if (atoi(first(s).c_str()) != x && atoi(second(s).c_str()) != x)
				{
    
    

					vf.push_back(s);
				}
			}
		}
		outfile.close();
		ofstream out1("worke.txt");
		out1.close();
		outfile.open("worke.txt", ios::app);
		for (int i = 0; i < vf.size(); i++)
		{
    
    
			outfile << vf[i] << endl;
		}
		outfile.close();
	}
	//删除队伍
	void dev()
	{
    
    
		system("cls");
		cout << "当前功能为删除地点" << endl;
		int n;
		cout << "请输入删除地点的个数:";
		cin >> n;
		int x;
		for (int i = 0; i < n; i++)
		{
    
    
			cout << "请输入删除地点的编号:";
			while (1)
			{
    
    
				cin >> x;
				if (existvertex(x))
				{
    
    
					deletevertex(x);
					devf(x);
					cout << "点" << x << "删除成功!" << endl;
					break;
				}
				else
				{
    
    
					cout << "点" << x << "不存在!请重新输入:" << endl;
					continue;
				}
			}
		}
		int a;
		cout << "返回主页请按0 继续删除请按1" << endl;
		cin >> a;
		if (a)
		{
    
    
			dev();
		}
		else
		{
    
    
			return;
		}

	}
	//在文件中写入边x->y
	void adef(int x, int y) {
    
    
		ofstream outfile;
		outfile.open("worke.txt", ios::app);
		outfile << x << " " << y << endl;
		outfile.close();
	}
	//添加联系
	void ade()
	{
    
    
		system("cls");
		cout << "当前功能为添加联系" << endl;
		int n;
		cout << "请输入添加联系的个数:";
		cin >> n;
		int x, y;
		for (int i = 0; i < n; i++)
		{
    
    
			while (1) {
    
    
				cout << "请输入起始队伍:";
				while (1) {
    
    
					cin >> x;
					if (legalvertex(x))
					{
    
    
						break;
					}
					else {
    
    
						cout << "队伍不规范!请重新输入:" << endl;
					}
				}
				if (!existvertex(x))
				{
    
    
					int p;
					cout << "不存在队伍" << x << ",是否要添加队伍" << x << "?" << endl;
					cout << "是请按1       否请按2" << endl;
					cin >> p;
					if (p == 1)
					{
    
    
						this->adv(x);
					}
					else
					{
    
    
						if (p == 2)
						{
    
    
							break;
						}
					}
				}
				cout << endl;
				cout << "请输入终点队伍:";
				while (1) {
    
    
					cin >> y;
					if (legalvertex(y))
					{
    
    
						break;
					}
					else {
    
    
						cout << "队伍不规范!请重新输入:" << endl;
					}
				}
				if (!existvertex(y))
				{
    
    
					int p;
					cout << "不存在队伍" << y << ",是否要添加队伍" << y << "?" << endl;
					cout << "是请按1       否请按2" << endl;
					cin >> p;
					if (p == 1)
					{
    
    
						this->adv(y);
					}
					else
					{
    
    
						if (p == 2)
						{
    
    
							break;
						}
					}
				}

				if (existsEdge(reindex(x), y)) {
    
    
					cout << "已经存在该联系! " << endl;
					continue;
				}
				else
				{
    
    
					edge<T>* ed = new edge<T>(x, y);
					insertEdge(ed); 
					adef(x, y);
					cout << "联系(" << x << "," << y << ")添加成功!" << endl;
					break;
				}
			}

		}
		int a;
		cout << "返回主页请按0 继续添加请按1" << endl;
		cin >> a;
		if (a)
		{
    
    
			ade();
		}
		else
		{
    
    
			return;
		}
	}
	//删除边的文件操作
	void deef(int x, int y) {
    
    
		vector<string>vf;
		string s;
		fstream outfile;
		outfile.open("worke.txt");
		while (!outfile.eof())
		{
    
    
			getline(outfile, s);
			if (s != "")
			{
    
    
				if (atoi(first(s).c_str()) != x || atoi(second(s).c_str()) != y)
				{
    
    

					vf.push_back(s);
				}
			}
		}
		outfile.close();
		ofstream out("worke.txt");
		out.close();
		outfile.open("worke.txt", ios::app);
		for (int i = 0; i < vf.size(); i++)
		{
    
    
			outfile << vf[i] << endl;
		}
		outfile.close();
	}
	//删除联系
	void dee()
	{
    
    
		system("cls");
		cout << "当前功能为删除联系" << endl;
		int n;
		cout << "请输入删除联系的个数:";
		cin >> n;
		int x, y;
		for (int i = 0; i < n; i++)
		{
    
    
			cout << "请输入起始队伍:";
			while (1) {
    
    
				cin >> x;
				if (!existvertex(x))
				{
    
    
					cout << "不存在队伍" << x << endl;
					cout << "请重新输入:";
				}
				else
				{
    
    
					break;
				}
			}
			cout << "请输入终点队伍:";
			while (1) {
    
    
				cin >> y;
				if (!existvertex(y))
				{
    
    
					cout << "不存在队伍" << y << endl;
					cout << "请重新输入:";
				}
				else
				{
    
    
					break;
				}
			}
			if (existsEdge(reindex(x), y))
			{
    
    
				eraseEdge(x, y);
				deef(x, y);
			}
			cout << "边(" << x << "," << y << ")删除成功!" << endl;
		}
		int a;
		cout << "返回主页请按0 继续删除请按1" << endl;
		cin >> a;
		if (a)
		{
    
    
			dee();
		}
		else
		{
    
    
			return;
		}
	}
	//拓扑排序
	int* Topologicalsorting() {
    
    
		int* in = new int[num + 1];
		int* result = new int[num + 1];
		int* visited = new int[num + 1];
		int j = 0;
		int k = 0;
		fill(visited, visited + num + 1, 0);
		stack<int>zero;
		for (int i = 1; i <= num; i++)
		{
    
    
			in[i] = W[i].indegree;
			if (W[i].indegree == 0)
			{
    
    
				zero.push(i);
				visited[i] = 1;
			}
		}
		while (!zero.empty())
		{
    
    
			j = zero.top();
			zero.pop();
			result[k++] = W[j].ver;
			for (int i = 0; i < E[j].g.size(); i++)
			{
    
    
				in[reindex(E[j].g[i].number)]--;
			}
			for (int i = 1; i <= num; i++)
			{
    
    
				if (visited[i] == 0 && in[i] == 0) {
    
    
					zero.push(i);
					visited[i] = 1;
				}
			}
		}
		for (int i = 1; i <= num; i++)
		{
    
    
			if (visited[i] == 0)
			{
    
    
				cout << "无法得出拓扑排序存在孤立点" << endl;
				return result;
			}
		}
		cout << "拓扑排序为:";
		for (int i = 0; i < num - 1; i++) {
    
    
			cout << W[reindex(result[i])].name << "->";
		}
		cout << W[reindex(result[num - 1])].name << endl;
	}
	//拓扑排序方法
	void tuopu() {
    
    
		system("cls");
		cout << "当前功能为拓扑排序,为任务进行排序" << endl;
		cout << "排序结果为:" << endl;
		if (edges == 0)
		{
    
    
			for (int i = 1; i < W.size(); i++)
			{
    
    
				cout << W[i].ver << " ";
			}
			cout << endl;
			cout << "返回主页面请按任意键" << endl;
			system("pause");
			return;
		}
		int* arr = Topologicalsorting();
		cout << endl;
		cout << "返回主页面请按任意键" << endl;
		system("pause");
	}
	//文件流初始化
	void Automaticinitialization() {
    
    
		system("cls");
		cout << "当前为自动初始化" << endl;
		cout << "初始化中......." << endl;
		fstream outfile;
		outfile.open("workv.txt");
		string s;
		int x, y;
		string na;
		while (!outfile.eof())
		{
    
    
			getline(outfile, s);
			if (s != "")
			{
    
    
				x = atoi(first(s).c_str());
				na = second(s);
				addvertex(x, na);
			}
		}
		outfile.close();
		fstream out;
		out.open("worke.txt");
		while (!out.eof())
		{
    
    
			getline(out, s);
			if (s != "")
			{
    
    
				x = atoi(first(s).c_str());
				y = atoi(second(s).c_str());
				edge<T>* ed = new edge<T>(x, y);
				insertEdge(ed);
			}
		}
		out.close();
		system("cls");
		cout << "初始化完成" << endl;
		system("pause");
	}
	//初始化
	void initialization() {
    
    
		int a;
		bool flag = false;
		while (1)
		{
    
    
			if (flag) {
    
    
				break;
			}
			system("cls");
			cout << "********************************" << endl;
			cout << "**********队伍安排模块**********" << endl;
			cout << "功能如下:" << endl;
			cout << "1.增加队伍" << endl;
			cout << "2.增加队伍联系" << endl;
			cout << "3.删除队伍" << endl;
			cout << "4.删除队伍联系" << endl;
			cout << "5.队伍顺序安排" << endl;
			cout << "6.自动初始化" << endl;
			cout << "7.退出" << endl;
			cout << "选择您需要的功能:" << endl;
			cin >> a;
			switch (a)
			{
    
    
			case 1:adv(); break;
			case 2:ade(); break;
			case 3:dev(); break;
			case 4:dee(); break;
			case 5:tuopu(); break;
			case 6:Automaticinitialization(); break;
			case 7:flag = true; break;
			}
		}
	}
};
#endif

arrayWDigraph.h

#pragma once
#ifndef arrayWDigraph_
#define  arrayWDigraph_
#include"graph.h"
#include"edge.h"
#include"node.h"
#include "vertexIterator.h"
#include"work.h"
#include<stack>
#include<string>
#include<vector>
#include<fstream>
#include <sstream>
#include<iostream>
template<class T>
class arrayWDgraph :public graph<T> {
    
    
protected:
	struct VE {
    
    
		int ve;
		vector<node <T>> g;
	};
	const T mx = 10000;
	int vertex;//顶点数
	int edges;//边数
	vector<VE> G;//存储图中的边
	vector<nodeform>V;//存储图中的点
	int* visited;//是否访问过
	int length;//路径长度
	int** pa;//佛洛依德的路径
	T** dis;//佛洛依德的距离
	int* dpath;                                                      //储存路径
	//dijkstra专用
	bool* canreach;                                            //某点是否可达
	T* ddis;                                                           //到某点的最少费用
	stack<int>theShortest;
public:
	//构造函数
	arrayWDgraph(int v = 0) {
    
    
		while (1)
		{
    
    

			if (v < 0)
			{
    
    
				cout << "输入不标准!请重新输入:" << endl;
				cin >> v;
			}
			else
			{
    
    
				break;
			}
		}
		vertex = v;
		edges = 0;
		visited = new int[vertex + 1];
		V = vector<nodeform>(vertex + 1);
		pa = NULL;
		dis = NULL;
		dpath = NULL;
		ddis = NULL;
		canreach = NULL;
		G = vector<VE>{
    
     (unsigned int)(vertex + 1),VE() };
	};
	~arrayWDgraph() {
    
    };
	//string转化为T
	T stringToNum(const string& str)
	{
    
    
		istringstream iss(str);
		T num;
		iss >> num;
		return num;
	}
	//获取编号为x的点的索引
	int reindex(int x) {
    
    
		for (int i = 1; i <= vertex; i++)
		{
    
    
			if (V[i].ver == x)
			{
    
    
				return i;
			}
		}
	}
	//获取点的个数
	int numberOfVertices() const {
    
    
		return vertex;
	};
	//获取边的个数
	int numberOfEdges() const {
    
    
		return edges;
	};
	//判断是否存在边a->b
	bool existsEdge(int a, int b) const {
    
    
		int c = G[a].g.size();
		for (int i = 0; i < c; i++)
		{
    
    
			if (G[a].g[i].number == b)
			{
    
    
				return true;
			}
		}
		return false;
	};
	//判断是否已经存在点v
	bool existvertex(int v)
	{
    
    
		for (int i = 0; i < V.size(); i++)
		{
    
    
			if (v == V[i].ver)
			{
    
    
				return true;
			}
		}
		return false;
	}
	//判断边v1->v2是否合法
	bool legaledge(int v1, int v2)
	{
    
    
		if (v1 < 1 || v2 < 1)
		{
    
    
			return false;
		}
		else
		{
    
    
			return true;
		}
	};
	//判断点v是否合法
	bool legalvertex(int v) {
    
    
		if (v >= 1)
		{
    
    
			return true;
		}
		else
		{
    
    
			cout << "点不合法!" << endl;
			return false;
		}
	}
	//用来判断输入的占领值是否合法
	bool legaloccupy(int x) {
    
    
		if (x == 1 || x == 0)
		{
    
    
			return true;
		}
		return false;
	}
	//判断权值是否合法
	bool legalweight(T w) {
    
    
		if (w < 0)
		{
    
    
			return false;
		}
		else
		{
    
    
			return true;
		}
	}
	//增加边
	void insertEdge(edge<T>* Edge) {
    
    
		int v1 = Edge->getS1();
		int v2 = Edge->getS2();
		T w = Edge->getW();
		if (!legaledge(v1, v2))
		{
    
    
			return;
		}
		int v = reindex(v1);
		if (existsEdge(reindex(v1), v2))
		{
    
    
			auto p = G[v].g.begin();
			for (int i = 0; i < G[v].g.size(); i++)
			{
    
    
				if (G[v].g[i].number == v2)
				{
    
    
					p = find(G[v].g.begin(), G[v].g.end(), v2);
				}
			}
			p->weight = w;
		}
		else
		{
    
    
			V[reindex(v2)].indegree++;
			V[v].outdegree++;
			node<T> no(v2, w);
			G[v].g.push_back(no);
			edges++;
		}
	};
	//删除边
	bool eraseEdge(int v1, int v2) {
    
    
		int v = reindex(v1);
		if (!legaledge(v1, v2))
		{
    
    
			return false;
		}
		if (!existsEdge(reindex(v1), v2))
		{
    
    
			return false;
		}
		for (int i = 0; i < G[v].g.size(); i++)
		{
    
    
			if (G[v].g[i].number == v2)
			{
    
    
				G[v].g.erase(remove(G[v].g.begin(), G[v].g.end(), v2), G[v].g.end());
				V[v].outdegree--;
				V[v].indegree--;
				edges--;
				break;
			}
		}
		return true;
	};
	//获取入度
	int indegree(int v) const {
    
    
		return V[v].indegree;
	};
	//获取入度子方法
	int idg(int x) {
    
    
		return indegree(reindex(x));
	}
	//获取出度
	int outdegree(int v) const {
    
    
		return V[v].outdegree;
	};
	//获取出度子方法
	int odg(int x) {
    
    
		return outdegree(reindex(x));
	}
	//获取度
	int degree(int v) const {
    
    
		return indegree(v) + outdegree(v);
	};
	//是否为有向图
	bool directed()  const {
    
     return true; };
	//是否为有权图
	bool weighted()  const {
    
     return true; };
	//被DFS调用
	void rDFS(int start, int label) {
    
    
		visited[start] = label;
		auto pointer = iterator(start);
		int now;
		while ((now = pointer->next()) != 0) {
    
    
			if (visited[now] == 0)
				rDFS(now, label);
		}
		delete pointer;
	}
	//被dfs调用
	void sdfs(int start, int label) {
    
    
		visited[start] = label;
		auto pointer = G[start].g.begin();
		int now;
		while (pointer != G[start].g.end()) {
    
    
			now = pointer->number;
			if (visited[now] == 0)
				sdfs(now, label);
			pointer++;
		}
	}
	//迭代器的继承
	class myIterator : public vertexIterator<T> {
    
    
	public:
		myIterator(VE& thelist) {
    
    //传入引用,减小开销
			newlist = thelist.g;
			size = newlist.size() - 1;//初始化
			cur = 0;
		};
		int next() {
    
    //取出当前,指向后一个
			if (cur > size)return 0;//终止
			int nextVertex = newlist[cur].number;//取出权值和下标	
			cur++;//游标后移
			return nextVertex;
		};
		int next(T& theWeight) {
    
    
			if (cur > size)return 0;	//终止				
			int nextVertex = newlist[cur].number;//取出权值和下标
			theWeight = newlist[cur].weight;
			cur++;//游标后移
			return nextVertex;
		};
		int next(T& theWeight, int& pos) {
    
    
			if (cur > size)return 0;	//终止				
			int nextVertex = newlist[cur].number;//取出权值和下标
			theWeight = newlist[cur].weight;
			pos = cur++;//游标后移		
			return nextVertex;
		};
		void reset() {
    
     cur = 0; }//重置游标
	protected:
		vector<node<T>>newlist;
		int x;
		int cur;
		int size;
	};
	//迭代器的方法
	myIterator* iterator(int x) {
    
    
		if (legalvertex(x)) {
    
    
			return new myIterator(G[reindex(x)]);//为类中传入边表,因为该类无法使用主类中的nodes
		}
	};
	//自带的迭代器dfs
	void dfs(int start, int label) {
    
    
		if (!legalvertex(start))return;
		visited = new int[vertex + 1];
		fill(visited, visited + vertex + 1, 0);
		sdfs(start, label);
	}
	//课本的迭代器的DFS
	void DFS(int start, int label) {
    
    
		if (!legalvertex(start))return;
		visited = new int[vertex + 1];
		fill(visited, visited + vertex + 1, 0);
		rDFS(start, label);
	}
	//返回第一部分的字符串
	string first(string s) {
    
    
		string f;
		for (int i = 0; i < s.size(); i++)
		{
    
    
			if (s[i] == ' ')
			{
    
    
				f = s.substr(0, i + 1);
				break;
			}
		}
		return f;
	}
	//返回第二部分的字符串
	string second(string s) {
    
    
		string f;
		bool flag = false;
		int x;
		for (int i = 0; i < s.size(); i++)
		{
    
    
			if (s[i] == ' ' && !flag)
			{
    
    
				flag = true;
				x = i;
			}
			else
			{
    
    
				if (s[i] == ' ' && flag)
				{
    
    
					f = s.substr(x + 1, i - x);
					break;
				}
			}
		}
		return f;
	}
	//返回第三部分的字符串
	string third(string s) {
    
    
		string f;
		bool flag = false;
		int x;
		for (int i = 0; i < s.size(); i++)
		{
    
    
			if (s[i] == ' ' && !flag)
			{
    
    
				flag = true;
				x = i;
			}
			else
			{
    
    
				if (s[i] == ' ' && flag)
				{
    
    
					f = s.substr(i + 1, s.size() - i - 1);
					break;
				}
			}
		}
		return f;
	}
	//返回第一个空格位置的索引
	int reoneblank(string s) {
    
    
		int x;
		for (int i = 0; i < s.size(); i++)
		{
    
    
			if (s[i] == ' ')
			{
    
    
				x = i;
				break;
			}
		}
		return x;
	}
	//返回第二个空格的位置的索引
	int retwoblank(string s) {
    
    
		int x;
		bool flag = false;
		for (int i = 0; i < s.size(); i++)
		{
    
    
			if (s[i] == ' ' && !flag)
			{
    
    
				flag = true;
			}
			else
			{
    
    
				if (s[i] == ' ' && flag)
				{
    
    
					x = i;
					break;
				}
			}
		}
		return x;
	}
	//在文件中更新权值
	void updwf(int x, int y, T z) {
    
    
		vector<string>vf;
		string s;
		fstream outfile;
		outfile.open("edges.txt");
		while (!outfile.eof())
		{
    
    
			getline(outfile, s);
			if (atoi(first(s)) == x && atoi(second(s)) == y)
			{
    
    
				s = s.substr(0, retwoblank(s));
				string c = to_string(z);
				s += c;
				vf.push_back(s);
			}
			else
			{
    
    
				if (s != "")
				{
    
    
					vf.push_back(s);
				}
			}
		}
		outfile.close();
		ofstream out("edges.txt");
		out.close();
		outfile.open("edges.txt", ios::app);
		for (int i = 0; i < vf.size(); i++)
		{
    
    
			outfile << vf[i] << endl;
		}
		outfile.close();
	}
	//更新权值
	void updateweight(int v1, int v2, T w) {
    
    
		int c = G[reindex(v1)].g.size();
		for (int i = 0; i < c; i++)
		{
    
    
			if (G[reindex(v1)].g[i].number == v2)
			{
    
    
				G[reindex(v1)].g[i].weight = w;
			}
		}
		cout << "更新成功!" << endl;
		int a;
		cout << "返回主页请按0 继续添加请按1" << endl;
		cin >> a;
		switch (a) {
    
    
		case 1:ade(); break;
		case 0:return;
		}
	}
	//增加点
	void addvertex(int v, string na, int ocu = 0) {
    
    
		nodeform node(ocu, v, na);
		V.push_back(node);
		VE nod;
		nod.ve = v;
		nod.g.clear();
		G.push_back(nod);
		vertex++;
	}
	//删除点
	void deletevertex(int v) {
    
    
		int x = reindex(v);
		int num = G[x].g.size();
		G.erase(G.begin() + x, G.begin() + x + 1);
		edges -= num;
		V.erase(V.begin() + x, V.begin() + x + 1);
		vertex--;
		for (int i = 1; i < G.size(); i++)
		{
    
    
			for (int j = 0; j < G[i].g.size(); j++)
			{
    
    
				if (G[i].g[j].number == v)
				{
    
    
					G[i].g.erase(G[i].g.begin() + j, G[i].g.begin() + j + 1);
					V[i].outdegree--;
				}
			}
		}
	}
	//在文件中写入点x
	void advf(int x, string y, int z) {
    
    
		ofstream outfile;
		outfile.open("vertex.txt", ios::app);
		outfile << x << " " << y << " " << z << endl;
		outfile.close();
	}
	//添加地点
	void adv()
	{
    
    
		system("cls");
		cout << "当前功能为添加地点" << endl;
		int n;
		cout << "请输入添加的点的个数:";
		cin >> n;
		int x, o;
		string y;
		for (int i = 0; i < n; i++)
		{
    
    
			cout << "请输入点的编号:";
			while (1)
			{
    
    
				cin >> x;
				if (!legalvertex(x))
				{
    
    
					cout << "请重新输入:";
					continue;
				}
				else if (existvertex(x))
				{
    
    
					cout << " 该点已经存在!" << endl;
					cout << "请重新输入:";
					continue;
				}
				break;
			}
			cout << "请输入点的名字:";
			cin >> y;
			cout << "该点是否已经被占领(0为否,1为是):";
			cin >> o;
			while (1)
			{
    
    
				if (legaloccupy(o))
				{
    
    
					addvertex(x, y, o);
					advf(x, y, o);
					cout << "点" << x << "增加成功!" << endl;
					break;
				}
				else
				{
    
    
					cout << "输入不规范,请重新输入:";
					cin >> o;
				}
			}
		}
		int a;
		cout << "返回主页请按0 继续添加请按1" << endl;
		cin >> a;
		switch (a) {
    
    
		case 1:adv(); break;
		case 0:return;
		}
	}
	//添加地点重载函数
	void adv(int x)
	{
    
    
		string y;
		int o;
		cout << "请输入点的名字:";
		cin >> y;
		cout << "该点是否已经被占领(0为否,1为是):";
		cin >> o;
		while (1)
		{
    
    
			if (legaloccupy(o))
			{
    
    
				addvertex(x, y, o);
				advf(x, y, o);
				cout << "点" << x << "增加成功!" << endl;
				break;
			}
			else
			{
    
    
				cout << "输入占领情况不规范,请重新输入:";
				cin >> o;
				continue;
			}
		}
	}
	//删除点的文件操作
	void devf(int x) {
    
    
		vector<string>vf;
		string s;
		fstream outfile;
		outfile.open("vertex.txt");
		while (!outfile.eof())
		{
    
    
			getline(outfile, s);
			if (atoi(first(s).c_str()) != x && s != "")
			{
    
    
				vf.push_back(s);
			}
		}
		outfile.close();
		ofstream out("vertex.txt");
		out.close();
		outfile.open("vertex.txt", ios::app);
		for (int i = 0; i < vf.size(); i++)
		{
    
    
			outfile << vf[i] << endl;
		}
		outfile.close();
		vf.clear();
		outfile.open("edges.txt");
		while (!outfile.eof())
		{
    
    
			getline(outfile, s);
			if (s != "")
			{
    
    
				if (atoi(first(s).c_str()) != x && atoi(second(s).c_str()) != x)
				{
    
    

					vf.push_back(s);
				}
			}
		}
		outfile.close();
		ofstream out1("edges.txt");
		out1.close();
		outfile.open("edges.txt", ios::app);
		for (int i = 0; i < vf.size(); i++)
		{
    
    
			outfile << vf[i] << endl;
		}
		outfile.close();
	}
	//删除地点
	void dev()
	{
    
    
		system("cls");
		if (vertex == 0)
		{
    
    
			cout << "一个点也没有!" << endl;
			system("pause");
			return;
		}
		else
		{
    
    
			cout << "当前功能为删除地点" << endl;
			int n;
			cout << "请输入删除地点的个数:";
			cin >> n;
			int x;
			for (int i = 0; i < n; i++)
			{
    
    
				cout << "请输入删除地点的编号:";
				cin >> x;
				deletevertex(x);
				devf(x);
				cout << "点" << x << "删除成功!" << endl;
			}
			int a;
			cout << "返回主页请按0 继续删除请按1" << endl;
			cin >> a;
			switch (a) {
    
    
			case 1:dev(); break;
			case 0:return;
			}
		}
	}
	//在文件中写入边x->y
	void adef(int x, int y, T z) {
    
    
		ofstream outfile;
		outfile.open("edges.txt", ios::app);
		outfile << x << " " << y << " " << z << endl;
		outfile.close();
	}
	//添加路
	void ade()
	{
    
    
		system("cls");
		cout << "当前功能为添加路" << endl;
		int n;
		cout << "请输入添加路的个数:";
		cin >> n;
		int x, y;
		T w;
		for (int i = 0; i < n; i++)
		{
    
    
			cout << "请输入起点:";
			while (1) {
    
    
				cin >> x;
				if (legalvertex(x))
				{
    
    
					break;
				}
				else {
    
    
					cout << "点不规范!请重新输入:" << endl;
				}
			}
			if (!existvertex(x))
			{
    
    
				int p;
				cout << "不存在点" << x << ",是否要添加点" << x << "?" << endl;
				cout << "是请按1       否请按2" << endl;
				cin >> p;
				switch (p) {
    
    
				case 1:this->adv(x); break;
				case 2:return;
				}
			}
			cout << endl;
			cout << "请输入终点:";
			while (1) {
    
    
				cin >> y;
				if (legalvertex(y))
				{
    
    
					break;
				}
				else {
    
    
					cout << "点不规范!请重新输入:" << endl;
				}
			}
			if (!existvertex(y))
			{
    
    
				int p;
				cout << "不存在点" << y << ",是否要添加点" << y << "?" << endl;
				cout << "是请按1       否请按2" << endl;
				cin >> p;
				switch (p) {
    
    
				case 1:this->adv(y); break;
				case 2:return;
				}
			}
			if (existsEdge(reindex(x), y)) {
    
    
				cout << "已经存在该路径,是否要更新权值? 否请按0,是请按1 " << endl;
				int p;
				cin >> p;
				switch (p)
				{
    
    
				case 0:return;
				case 1: {
    
    cout << "请输入路径的权值:";
					while (1)
					{
    
    
						cin >> w;
						if (legalweight(w))
						{
    
    
							break;
						}
						else
						{
    
    
							cout << "输入的权值不规范!请重新输入:" << endl;
						}
					}
					updateweight(x, y, w);
					return; }
				}
			}
			cout << "请输入路径的权值:";
			while (1)
			{
    
    
				cin >> w;
				if (legalweight(w))
				{
    
    
					break;
				}
				else
				{
    
    
					cout << "输入的权值不规范!请重新输入:" << endl;
				}
			}
			edge<T>* ed = new edge<T>(x, y, w);
			insertEdge(ed);
			adef(x, y, w);
			cout << "边";
			ed->output();
			cout << "添加成功!" << endl;
		}
		int a;
		cout << "返回主页请按0 继续添加请按1" << endl;
		cin >> a;
		switch (a) {
    
    
		case 0:return;
		case 1:ade(); break;
		}
	}
	//删除路的文件操作
	void deef(int x, int y) {
    
    
		vector<string>vf;
		string s;
		fstream outfile;
		outfile.open("edges.txt");
		while (!outfile.eof())
		{
    
    
			getline(outfile, s);
			if (s != "")
			{
    
    
				if (atoi(first(s).c_str()) != x || atoi(second(s).c_str()) != y)
				{
    
    

					vf.push_back(s);
				}
			}
		}
		outfile.close();
		ofstream out("edges.txt");
		out.close();
		outfile.open("edges.txt", ios::app);
		for (int i = 0; i < vf.size(); i++)
		{
    
    
			outfile << vf[i] << endl;
		}
		outfile.close();
	}
	//删除路
	void dee()
	{
    
    
		system("cls");
		if (edges == 0)
		{
    
    
			cout << "当前不存在路!" << endl;
			system("pause");
			return;
		}
		cout << "当前功能为删除路" << endl;
		int n;
		cout << "请输入删除路的个数:";
		cin >> n;
		int x, y;
		for (int i = 0; i < n; i++)
		{
    
    
			cout << "请输入起点:";
			while (1) {
    
    
				cin >> x;
				if (!existvertex(x))
				{
    
    
					cout << "不存在点" << x << endl;
					cout << "请重新输入:";
				}
				else
				{
    
    
					break;
				}
			}
			cout << "请输入终点:";
			while (1) {
    
    
				cin >> y;
				if (!existvertex(y))
				{
    
    
					cout << "不存在点" << y << endl;
					cout << "请重新输入:";
				}
				else
				{
    
    
					break;
				}
			}
			if (existsEdge(reindex(x), y))
			{
    
    
				eraseEdge(x, y);
				deef(x, y);
			}
			cout << "边(" << x << "," << y << ")删除成功!" << endl;
		}
		return;
	}
	//拓扑排序
	void Topologicalsorting() {
    
    
		int* in = new int[vertex + 1];
		int* result = new int[vertex + 1];
		int j = 0;
		int k = 0;
		visited= new int[vertex + 1];
		fill(visited, visited + vertex + 1, 0);
		stack<int>zero;
		for (int i = 1; i <= vertex; i++)
		{
    
    
			in[i] = V[i].indegree;
			if (V[i].indegree == 0)
			{
    
    
				zero.push(i);
				visited[i] = 1;
			}
		}
		while (!zero.empty())
		{
    
    
			j = zero.top();
			zero.pop();
			result[k++] = V[j].ver;
			for (int i = 0; i < G[j].g.size(); i++)
			{
    
    
				in[reindex(G[j].g[i].number)]--;
			}
			for (int i = 1; i <= vertex; i++)
			{
    
    
				if (visited[i] == 0 && in[i] == 0) {
    
    
					zero.push(i);
					visited[i] = 1;
				}
			}
		}
		for (int i = 1; i <= vertex; i++)
		{
    
    
			if (visited[i] == 0)
			{
    
    
				cout << "无法得出拓扑排序!出现点之间的关系无法拓扑!" << endl;
				return;
			}
		}
		cout << "拓扑排序为:";
		for (int i = 0; i < vertex - 1; i++) {
    
    
			cout << V[reindex(result[i])].name << "->";
		}
		cout << V[reindex(result[vertex - 1])].name << endl;
	}
	//拓扑排序方法
	void tuopu() {
    
    
		system("cls");
		if (vertex == 0)
		{
    
    
			cout << "一个点也没有!" << endl;
			system("pause");
			return;
		}
		cout << "当前功能为拓扑排序,为地点进行排序" << endl;
		cout << "排序结果为:" << endl;
		if (edges == 0)
		{
    
    
			for (int i = 1; i < V.size(); i++)
			{
    
    
				cout << V[i].ver << " ";
			}
			cout << endl;
			cout << "返回主页面请按任意键" << endl;
			system("pause");
			return;
		}
		Topologicalsorting();
		cout << endl;

		system("pause");
	}
	//更该点的占领情况的文件操作
	void alterocf(int x) {
    
    
		vector<string>vf;
		string s, n;
		fstream outfile;
		outfile.open("vertex.txt");
		while (!outfile.eof())
		{
    
    
			getline(outfile, s);
			if (s[0] - '0' == x && s != "")
			{
    
    
				n = s.substr(0, 4);
				if (s[4] - '0' == 0)
				{
    
    
					n += "1";
				}
				else
				{
    
    
					n += "0";
				}
				vf.push_back(n);
			}
			else
			{
    
    
				vf.push_back(s);
			}
		}
		outfile.close();
		ofstream out("vertex.txt");
		out.close();
		outfile.open("vertex.txt", ios::app);
		for (int i = 0; i < vf.size(); i++)
		{
    
    
			outfile << vf[i] << endl;
		}
		outfile.close();
	}
	//更改点的占领情况的文件操作
	void alteroc(int x) {
    
    
		if (V[x].occupy)
		{
    
    
			V[x].occupy = 0;
		}
		else
		{
    
    
			V[x].occupy = 1;
		}
	}
	//更改点的占领情况
	void addoc() {
    
    
		system("cls");
		if (vertex == 0)
		{
    
    
			cout << "一个点也没有!" << endl;
			system("pause");
			return;
		}
		cout << "当前功能为更改点的占领情况" << endl;
		cout << "请输入要更改的点的编号:";
		int x;
		cin >> x;
		while (1)
		{
    
    

			if (!existvertex(x))
			{
    
    
				cout << "目标点不存在!请重新输入:";
				cin >> x;
				continue;
			}
			if (V[reindex(x)].occupy) {
    
    
				cout << "点" << x << "当前的占领情况为:已被占领" << endl;
			}
			else
			{
    
    
				cout << "点" << x << "当前的占领情况为:未被占领" << endl;
			}
			cout << "是否要更改占领情况?(是请按1 否请按0)" << endl;
			int p;
			cin >> p;
			switch (p)
			{
    
    
			case 1: {
    
    alteroc(reindex(x));
				alterocf(x);
				cout << "更改成功!" << endl;
				system("pause");
				return; }
			case 0:return;
			}
		}
		system("pause");
	}
	//连通集
	void Connected() {
    
    
		visited = new int[vertex + 1];
		fill(visited, visited + vertex + 1, 0);
		int a, b;
		b = 0;
		vector<vector<int>>lian;
		stack<int>sl;
		vector<int>du;
		for (int i = 1; i <= vertex; i++)
		{
    
    
			if (visited[i] == 0&&V[i].occupy==1)
			{
    
    
				sl.push(i);
				du.push_back(i);
				visited[i] = 1;
			}
			while (!sl.empty())
			{
    
    
				a = sl.top();
				sl.pop();
				for (int j = 0; j < G[a].g.size(); j++)
				{
    
    
					int re = reindex(G[a].g[j].number);
					if (visited[re] == 0 && V[re].occupy == 1)
					{
    
    
						sl.push(re);
						du.push_back(re);
						visited[re] = 1;
					}
				}
			}
			if (!du.empty()) {
    
    
				lian.push_back(du);
				b++;
				du.clear();
			}
		}
		if (!lian.empty())
		{
    
    
			cout << "已经占领了的点的连通集:" << endl;
			for (int i = 0; i < b; i++) {
    
    
				int x = 0;
				cout << "第" << i + 1 << "部分:";
				while (x<lian[i].size()) {
    
    
					cout << V[lian[i][x++]].ver << " ";
				}
				cout << endl;
			}
			cout << endl;
		}
		else
		{
    
    
			cout << "没有已占领的点!" << endl;
		}
		lian.clear();
		b = 0;
		for (int i = 1; i <= vertex; i++)
		{
    
    
			if (visited[i] == 0 && V[i].occupy == 0)
			{
    
    
				sl.push(i);
				du.push_back(i);
				visited[i] = 1;
			}
			while (!sl.empty())
			{
    
    
				a = sl.top();
				sl.pop();
				for (int j = 0; j < G[a].g.size(); j++)
				{
    
    
					int re = reindex(G[a].g[j].number);
					if (visited[re] == 0 && V[re].occupy == 0)
					{
    
    
						sl.push(re);
						du.push_back(re);
						visited[re] = 1;
					}
				}
			}
			if (!du.empty()) {
    
    
				lian.push_back(du);
				b++;
				du.clear();
			}
		}
		if (!lian.empty())
		{
    
    
			cout << "未占领的点的连通集:" << endl;
			for (int i = 0; i < b; i++) {
    
    
				int x = 0;
				cout << "第" << i + 1 << "部分:";
				while (x < lian[i].size()) {
    
    
					cout << V[lian[i][x++]].ver << " ";
				}
				cout << endl;
			}
			cout << endl;
		}
		else
		{
    
    
			cout << "没有未占领的点!" << endl;
		}
		
	}
	//每个点的占领情况
	void everyoc() {
    
    
		system("cls");
		if (vertex == 0)
		{
    
    
			cout << "一个点也没有!" << endl;
			system("pause");
			return;
		}
		for (int i = 1; i < V.size(); i++)
		{
    
    
			cout << "编号:" << V[i].ver << "占领情况:";
			if (V[i].occupy)cout << "已占领" << endl;
			else cout << "未占领" << endl;
		}
		Connected();
		system("pause");
	}
	//打印最短路径子方法
	void print_path(int i, int j) {
    
    
		int k = pa[i][j];
		if (k == -1)
			//说明没有中转顶点,直接返回.
			return;
		print_path(i, k);//寻找i和k之间
		cout << V[k].ver << "->";
		print_path(k, j);//寻找k和j之间
	}
	//打印最短路径
	void print_result() {
    
    
		int i, j;
		for (i = 1; i < vertex + 1; i++) {
    
    
			for (j = 1; j < vertex + 1; j++) {
    
    
				if (dis[i][j] == mx) {
    
    
					//无法到达设置距离为无穷大,则他们之前没有路径
					cout << V[i].ver << "和" << V[j].ver << "之间没有路径" << endl;
				}
				else {
    
    
					cout << V[i].ver << "和" << V[j].ver << "的最短路径为" << dis[i][j] << endl;
					cout << "路径方案为:" << V[i].ver << "->";
					print_path(i, j);
					cout << V[j].ver << endl;
				}
			}
		}
	}
	//佛洛依德算法
	void floyed() {
    
    
		dis = new  T * [vertex + 1];
		for (int i = 0; i < vertex + 1; i++)
		{
    
    
			dis[i] = new T[vertex + 1];
		}
		pa = new int* [vertex + 1];
		for (int i = 0; i < vertex + 1; i++)
		{
    
    
			pa[i] = new int[vertex + 1];
			for (int j = 0; j < vertex + 1; j++)
			{
    
    
				pa[i][j] = -1;
			}
		}
		for (int i = 0; i < vertex + 1; i++) {
    
    
			for (int j = 0; j < vertex + 1; j++) {
    
    
				if (i == j)dis[i][j] = 0;
				else dis[i][j] = mx;
			}
		}
		for (int i = 1; i < G.size(); i++)
		{
    
    
			for (int j = 0; j < G[i].g.size(); j++)
			{
    
    
				dis[i][reindex(G[i].g[j].number)] = G[i].g[j].weight;
			}
		}
		for (int k = 1; k < vertex + 1; k++) {
    
    
			//不断插点
			for (int i = 1; i < vertex + 1; i++) {
    
    
				for (int j = 1; j < vertex + 1; j++) {
    
    
					//对图中所有点之间的最短距离进行更新。
					if (dis[i][j] > dis[i][k] + dis[k][j]) {
    
    
						pa[i][j] = k;//记录中转顶点。
						dis[i][j] = dis[i][k] + dis[k][j];//更新。
					}
				}
			}
		}
	}
	//最短路径方法
	void foluo() {
    
    
		system("cls");
		if (vertex == 0)
		{
    
    
			cout << "图中没有点!" << endl;
			system("pause");
			return;
		}
		cout << "当前功能为每个地点间的最短路径" << endl;
		cout << "结果为:";
		floyed();
		print_result();
		cout << "***************************" << endl;
		system("pause");
	}
	//迪杰斯特拉算法
	void rdijkstra(int start)
	{
    
    
		int cnt = 1;
		for (int i = 1; i <= vertex - 1; i++) {
    
    //更新n-1次  
			T min = mx;
			int minnode = 0;
			for (int j = 1; j <= vertex; j++) {
    
    //j是下标
				if (ddis[j] < min && visited[j] == 0) {
    
    
					min = ddis[j];
					minnode = V[j].ver;//中转点的编号
				}
			}
			if (minnode == 0)
			{
    
    
				continue;
			}//没有可更新的点
			//path[minnode] = start;
			//没有路径的情况
			visited[reindex(minnode)] = 1;//已找到到达minnode的最短路径
			auto pointer = iterator(minnode);
			int next, pos;
			T weight;
			while ((next = pointer->next(weight, pos)) != 0) {
    
    
				if (visited[reindex(next)] == 0 && ddis[reindex(next)] > G[reindex(minnode)].g[pos].weight + ddis[reindex(minnode)]) {
    
    
					ddis[reindex(next)] = G[reindex(minnode)].g[pos].weight + ddis[reindex(minnode)];
					dpath[reindex(next)] = reindex(minnode);
				}
			}
		}
	}
	T* short_path_dijkstra(int start, int end)
	{
    
    
		ddis = new T[vertex + 1];
		fill(ddis, ddis + vertex + 1, mx);
		ddis[0] = vertex;
		ddis[start] = 0;
		dpath = new int[vertex + 1];
		dpath[start] = start;
		visited= new int[vertex + 1];
		fill(visited, visited + vertex + 1, 0);
		visited[start] = 1;
		auto pointer = iterator(V[start].ver);
		int next;
		T weight;
		while ((next = pointer->next(weight)) != 0) {
    
    
			ddis[reindex(next)] = weight;
			dpath[reindex(next)] = start;
		}
		rdijkstra(start);

		canreach = new bool[vertex + 1];
		for (int i = 1; i <= vertex; i++)
		{
    
    
			canreach[i] = true;
			if (ddis[i] == mx)
			{
    
    
				canreach[i] = false;
			}
		}
		if (canreach[end] == false)
		{
    
    
			return NULL;
		}
		stack<int>nothing;
		theShortest.swap(nothing);
		int cnt = 0;
		while (end != start) {
    
    
			theShortest.push(end);
			cnt++;
			end = dpath[end];
		}
		ddis[0] = cnt;
		canreach = NULL;
		return ddis;
	}
	void dijkstra_result(int start, int end)
	{
    
    
		start = reindex(start);//转换为索引
		end = reindex(end);
		T* distance = short_path_dijkstra(start, end);
		if (!distance) {
    
    
			cout << "不存在从" << V[start].ver << "到" << V[end].ver << "的路径" << endl;
			return;
		}
		T mindis = distance[0];
		cout << "从" << V[start].ver << "到" << V[end].ver << "的最短路径为" << ddis[end] << endl;
		cout << "其路径为:" << V[start].ver << "->";
		for (int i = 1; i <= mindis; i++)
		{
    
    
			cout << V[theShortest.top()].ver;
			if (i != mindis)
			{
    
    
				cout << "->";
			}
			theShortest.pop();
		}
		cout << endl;
	}
	void dijkstra()
	{
    
    
		system("cls");
		cout << "当前功能为单点最短路径" << endl;
		cout << "请输入作为单点的起点编号:" << endl;
		int qidian = 0;
		int zhongdian = 0;
		while (1) {
    
    
			cin >> qidian;
			if (!existvertex(qidian))
			{
    
    
				cout << "输入的起点不存在,请重新输入!" << endl;
			}
			else
			{
    
    
				break;
			}
		}
		cout << "请输入作为单点的终点编号:" << endl;
		while (1) {
    
    
			cin >> zhongdian;
			if (!existvertex(zhongdian))
			{
    
    
				cout << "输入的起点不存在,请重新输入!" << endl;
			}
			else
			{
    
    
				break;
			}
		}
	    if (qidian == zhongdian)
		{
    
    
			cout << "输入的起点与终点一致!" << endl;
			system("pause");
			return;
		}
		else {
    
    
			dijkstra_result(qidian, zhongdian);
		}
		system("pause");
	}
	//队伍模块
	void ranks() {
    
    
		works<double>K(0);
		K.initialization();
	}
	//清空图
	void allclear() {
    
    
		system("cls");
		if (vertex == 0)
		{
    
    
			cout << "图中没有点!" << endl;
			system("pause");
			return;
		}
		system("cls");
		cout << "正在清空......." << endl;
		G.clear();
		V.clear();
		vertex = 0;
		edges = 0;
		visited = new int[vertex + 1];
		V = vector<nodeform>(vertex + 1);
		pa = NULL;
		dis = NULL;
		dpath = NULL;
		ddis = NULL;
		canreach = NULL;
		G = vector<VE>{
    
     (unsigned int)(vertex + 1),VE() };
		system("cls");
		cout << "清空完成" << endl;
		system("pause");
	}
	//文件流初始化
	void Automaticinitialization() {
    
    
		system("cls");
		if (vertex != 0)
		{
    
    
			cout << "图还未清空,请勿初始化!" << endl;
			cout << "是否要清空图?是请按1,否请按0" << endl;
			int a;
			cin >> a;
			switch (a)
			{
    
    
			case 1:allclear(); break;
			case 0:return;
			}
		}
		system("cls");
		cout << "当前为自动初始化" << endl;
		cout << "初始化中......." << endl;
		fstream outfile;
		outfile.open("vertex.txt");
		string s;
		int x, y, z;
		string na;
		while (!outfile.eof())
		{
    
    
			getline(outfile, s);
			if (s != "")
			{
    
    
				x = atoi(first(s).c_str());
				na = second(s);
				z = atoi(third(s).c_str());
				addvertex(x, na, z);
			}
		}
		outfile.close();
		fstream out;
		out.open("edges.txt");
		string c;
		while (!out.eof())
		{
    
    
			getline(out, s);
			if (s != "")
			{
    
    
				x = atoi(first(s).c_str());
				y = atoi(second(s).c_str());
				c = third(s);
				T p = stringToNum(c);
				edge<T>* ed = new edge<T>(x, y, p);
				insertEdge(ed);
			}
		}
		out.close();
		system("cls");
		cout << "初始化完成" << endl;
		system("pause");
	}
	//初始化5个点
	void Ainitialization() {
    
    
		system("cls");
		if (vertex != 0)
		{
    
    
			cout << "图还未清空,请勿初始化!" << endl;
			cout << "是否要清空图?是请按1,否请按0" << endl;
			int a;
			cin >> a;
			switch (a)
			{
    
    
			case 1:allclear(); break;
			case 0:return;
			}
		}
		system("cls");
		cout << "当前为自动初始化" << endl;
		cout << "初始化中......." << endl;
		fstream outfile;
		outfile.open("vertex2.txt");
		string s;
		int x, y, z;
		string na;
		while (!outfile.eof())
		{
    
    
			getline(outfile, s);
			if (s != "")
			{
    
    
				x = atoi(first(s).c_str());
				na = second(s);
				z = atoi(third(s).c_str());
				addvertex(x, na, z);
			}
		}
		outfile.close();
		fstream out;
		out.open("edges2.txt");
		string c;
		while (!out.eof())
		{
    
    
			getline(out, s);
			if (s != "")
			{
    
    
				x = atoi(first(s).c_str());
				y = atoi(second(s).c_str());
				c = third(s);
				T p = stringToNum(c);
				edge<T>* ed = new edge<T>(x, y, p);
				insertEdge(ed);
			}
		}
		out.close();
		system("cls");
		cout << "初始化完成" << endl;
		system("pause");
	}
	//性能测试
	void performCompare() {
    
    
		//定制的
		system("cls");
		if (vertex == 0)
		{
    
    
			cout << "请先初始化!" << endl;
			system("pause");
			return;
		}
		system("cls");
		cout << "测试中........." << endl;
		clock_t start1, finish1;
		int label = 1, count1 = 0;
		start1 = clock();
		do
		{
    
    
			DFS(1, label);
			count1++;
		} while (((finish1 = clock()) - start1) < 1000);
		double x1 = ((double)finish1 - (double)start1) / count1;
		//自带的
		label = 1;
		int n = 0;
		clock_t start2, finish2;
		int count2 = 0;
		start2 = clock();
		do
		{
    
    
			dfs(1, label);
			count2++;
		} while (((finish2 = clock()) - start2) < 1000);
		double x2 = ((double)finish2 - (double)start2) / count2;
		system("cls");
		cout << "课本DFS运行时间:" << x1 << endl << "定制的的DFS运行时间:" << x2 << endl;
		system("pause");
	}
	//初始化
	void initialization() {
    
    
		bool flag = false;
		while (1)
		{
    
    
			int a;
			if (flag) {
    
    
				break;
			}
			system("cls");
			cout << "********************************" << endl;
			cout << "**********军事信息系统**********" << endl;
			cout << "功能如下:" << endl;
			cout << "1.增加地点" << endl;
			cout << "2.增加路" << endl;
			cout << "3.删除地点" << endl;
			cout << "4.删除路" << endl;
			cout << "5.更改点的占领情况" << endl;
			cout << "6.地点拓扑安排" << endl;
			cout << "7.单点最短路径" << endl;
			cout << "8.所有地点间最短路径" << endl;
			cout << "9.每个点的占领情况" << endl;
			cout << "10.队伍安排模块" << endl;
			cout << "11.自动初始化(100个点)" << endl;
			cout << "12.自动初始化(5个点)" << endl;
			cout << "13.清空全部" << endl;
			cout << "14.性能测试" << endl;
			cout << "15.退出" << endl;
			cout << "选择您需要的功能:" << endl;
			cin >> a;
			switch (a)
			{
    
    
			case 1:adv(); break;
			case 2:ade(); break;
			case 3:dev(); break;
			case 4:dee(); break;
			case 5:addoc(); break;
			case 6:tuopu(); break;
			case 7:dijkstra(); break;
			case 8:foluo(); break;
			case 9:everyoc(); break;
			case 10:ranks(); break;
			case 11:Automaticinitialization(); break;
			case 12:Ainitialization(); break;
			case 13:allclear(); break;
			case 14:performCompare(); break;
			case 15:flag = true; break;
			}
		}
	}
};
#endif

主函数文件

#include <iostream>
#include "arrayWDigraph.h"
int main()
{
    
    
	arrayWDgraph<double> W(0);
	W.initialization();
	return 0;
}

使用的算法(数据结构)

1.拓扑排序
2.佛洛依德算法
3.迪杰斯特拉算法
4.深度优先算法
5.广度优先算法
6.采用邻接数组的方式存储有向有权图

交互

该项目采用文件流的方式,交互所对应的结果会反映到文件中去。

猜你喜欢

转载自blog.csdn.net/qq_51314467/article/details/122771205