|
|
|
|
#include<iostream>
|
|
|
|
|
#include<fstream>
|
|
|
|
|
#include<graphics.h>
|
|
|
|
|
#include<string>
|
|
|
|
|
#include"MyGraph.h"
|
|
|
|
|
|
|
|
|
|
Edge::Edge() {
|
|
|
|
|
VerAdj = -1;
|
|
|
|
|
cost = -1;
|
|
|
|
|
link = NULL;
|
|
|
|
|
}
|
|
|
|
|
int& Edge::get_VerAdj() {
|
|
|
|
|
return VerAdj;
|
|
|
|
|
}
|
|
|
|
|
int& Edge::get_cost() {
|
|
|
|
|
return cost;
|
|
|
|
|
}
|
|
|
|
|
Edge*& Edge::get_link() {
|
|
|
|
|
return link;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Vertex::Vertex() {
|
|
|
|
|
VerName = "*";
|
|
|
|
|
Description = "*";
|
|
|
|
|
adjacent = NULL;
|
|
|
|
|
mark = x = y = -1;
|
|
|
|
|
}
|
|
|
|
|
std::string& Vertex::get_VerName() {
|
|
|
|
|
return VerName;
|
|
|
|
|
}
|
|
|
|
|
std::string& Vertex::get_Description() {
|
|
|
|
|
return Description;
|
|
|
|
|
}
|
|
|
|
|
Edge*& Vertex::get_adjacent() {
|
|
|
|
|
return adjacent;
|
|
|
|
|
}
|
|
|
|
|
int& Vertex::get_mark() {
|
|
|
|
|
return mark;
|
|
|
|
|
}
|
|
|
|
|
int& Vertex::get_x() {
|
|
|
|
|
return x;
|
|
|
|
|
}
|
|
|
|
|
int& Vertex::get_y() {
|
|
|
|
|
return y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int& Graph_List::get_MaxCost() {
|
|
|
|
|
return MaxCost;
|
|
|
|
|
}
|
|
|
|
|
Vertex* Graph_List::get_head() {
|
|
|
|
|
return head;
|
|
|
|
|
}
|
|
|
|
|
IMAGE* Graph_List::get_map() {
|
|
|
|
|
return map;
|
|
|
|
|
}
|
|
|
|
|
int Graph_List::get_index(int _mark) {
|
|
|
|
|
for (int i = 0; i < graphsize; i++) {
|
|
|
|
|
if (_mark == head[i].get_mark()) return i;
|
|
|
|
|
}
|
|
|
|
|
return -1; // <20>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-1
|
|
|
|
|
}
|
|
|
|
|
int Graph_List::get_index(std::string name) {
|
|
|
|
|
for (int i = 0; i < graphsize; i++) {
|
|
|
|
|
if (name == head[i].get_VerName()) return i;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
int Graph_List::graph_con(std::fstream& file, char* mapname) {
|
|
|
|
|
delete_Graph_List(); // <20>Ȱ<EFBFBD><C8B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD>ɾ<EFBFBD><C9BE>
|
|
|
|
|
map = new IMAGE;
|
|
|
|
|
loadimage(map, (LPCTSTR)mapname, 0, 0, false); // <20><><EFBFBD><EFBFBD>ͼƬ
|
|
|
|
|
file >> MaxCost;
|
|
|
|
|
file >> graphsize;
|
|
|
|
|
head = new Vertex[graphsize];
|
|
|
|
|
for (int i = 0; i < graphsize; i++) {
|
|
|
|
|
file >> head[i].get_VerName();
|
|
|
|
|
file >> head[i].get_Description();
|
|
|
|
|
file >> head[i].get_mark();
|
|
|
|
|
file >> head[i].get_x();
|
|
|
|
|
file >> head[i].get_y();
|
|
|
|
|
head[i].get_x() += LEFTBORDER;
|
|
|
|
|
head[i].get_y() += TOPBORDER;
|
|
|
|
|
head[i].get_adjacent() = NULL;
|
|
|
|
|
}
|
|
|
|
|
int edgenum;
|
|
|
|
|
file >> edgenum;
|
|
|
|
|
for (int j = 0; j < edgenum; j++) {
|
|
|
|
|
int v1, v2, weight;
|
|
|
|
|
file >> v1;
|
|
|
|
|
file >> v2;
|
|
|
|
|
double startx = head[get_index(v1)].get_x();
|
|
|
|
|
double starty = head[get_index(v1)].get_y();
|
|
|
|
|
double endx = head[get_index(v2)].get_x();
|
|
|
|
|
double endy = head[get_index(v2)].get_y();
|
|
|
|
|
weight = (double)sqrt((startx - endx) * (startx - endx) + (starty - endy) * (starty - endy));
|
|
|
|
|
insert_edge(get_index(v1), get_index(v2), weight);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
Graph_List::Graph_List() {
|
|
|
|
|
head = NULL;
|
|
|
|
|
map = new IMAGE;
|
|
|
|
|
graphsize = 0;
|
|
|
|
|
MaxCost = 0;
|
|
|
|
|
}
|
|
|
|
|
Graph_List::~Graph_List() {
|
|
|
|
|
delete_Graph_List();
|
|
|
|
|
}
|
|
|
|
|
int Graph_List::number_of_vertices()const {
|
|
|
|
|
return graphsize;
|
|
|
|
|
}
|
|
|
|
|
int Graph_List::number_of_edges()const {
|
|
|
|
|
int n = 0;
|
|
|
|
|
for (int i = 0; i < graphsize; i++) {
|
|
|
|
|
Edge* p = head[i].get_adjacent();
|
|
|
|
|
while (p) {
|
|
|
|
|
n++;
|
|
|
|
|
p = p->get_link();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return n / 2;
|
|
|
|
|
}
|
|
|
|
|
int Graph_List::save_file(char* filename) {
|
|
|
|
|
system("del filename"); // ɾ<><C9BE><EFBFBD>ļ<EFBFBD>
|
|
|
|
|
std::ofstream fl(filename); // <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
if (!fl) return -1;
|
|
|
|
|
fl << get_MaxCost() << std::endl; // <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
|
|
|
|
fl << number_of_vertices() << std::endl; // <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>
|
|
|
|
|
for (int i = 0; i < number_of_vertices(); i++) {
|
|
|
|
|
fl << head[i].get_VerName() << "\t\t\t" << head[i].get_Description()
|
|
|
|
|
<< "\t\t\t\t\t\t" << head[i].get_mark() << "\t"
|
|
|
|
|
<< head[i].get_x() - LEFTBORDER << "\t"
|
|
|
|
|
<< head[i].get_y() - TOPBORDER << std::endl;
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>
|
|
|
|
|
}
|
|
|
|
|
fl << std::endl;
|
|
|
|
|
int num_of_edges = number_of_edges() * 2; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> * 2 = <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
fl << num_of_edges << std::endl;
|
|
|
|
|
int num = 0;
|
|
|
|
|
for (int j = 0; j < number_of_vertices(); j++) {
|
|
|
|
|
Edge* p = head[j].get_adjacent();
|
|
|
|
|
while (p) {
|
|
|
|
|
if (num == 5) {
|
|
|
|
|
fl << std::endl;
|
|
|
|
|
num = 0;
|
|
|
|
|
}
|
|
|
|
|
fl << get_head()[j].get_mark() << "\t" << get_head()[p->get_VerAdj()].get_mark() << std::endl;
|
|
|
|
|
p = p->get_link();
|
|
|
|
|
num++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fl.close();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
bool Graph_List::is_graph_empty() {
|
|
|
|
|
return graphsize == 0;
|
|
|
|
|
}
|
|
|
|
|
int Graph_List::get_weight(const int& v1, const int& v2) {
|
|
|
|
|
if (v1 > graphsize - 1 || v2 > graphsize - 1 || v1 < 0 || v2 < 0) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (v1 == v2) return 0;
|
|
|
|
|
Edge* p = head[v1].get_adjacent();
|
|
|
|
|
while (p != NULL && p->get_VerAdj() != v2) p = p->get_link();
|
|
|
|
|
if (p) return p->get_cost();
|
|
|
|
|
else return MaxCost + 1; // <20><><EFBFBD><EFBFBD>֮<EFBFBD><D6AE>û<EFBFBD>б<EFBFBD><D0B1>ش<F2B7B5BB>ֵ
|
|
|
|
|
}
|
|
|
|
|
void Graph_List::insert_vertex(std::string _name, std::string _des, int _mark, int _x, int _y) {
|
|
|
|
|
Vertex* h = new Vertex[graphsize + 1]; // <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>µĶ<C2B5><C4B6><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
for (int i = 0; i < graphsize; i++) h[i] = head[i];
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵĶ<D3B5><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¶<EFBFBD><C2B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
h[graphsize].get_VerName() = _name;
|
|
|
|
|
h[graphsize].get_Description() = _des;
|
|
|
|
|
h[graphsize].get_mark() = _mark;
|
|
|
|
|
h[graphsize].get_x() = _x;
|
|
|
|
|
h[graphsize].get_y() = _y;
|
|
|
|
|
h[graphsize].get_adjacent() = NULL;
|
|
|
|
|
delete[] head;
|
|
|
|
|
head = h;
|
|
|
|
|
graphsize++;
|
|
|
|
|
}
|
|
|
|
|
int Graph_List::insert_edge(int v1, int v2, int weight) {
|
|
|
|
|
if (v1 > graphsize - 1 || v2 > graphsize - 1 || v1 < 0 || v2 < 0) {
|
|
|
|
|
return -1; // <20><><EFBFBD><EFBFBD>Ԫ<EFBFBD>س<EFBFBD><D8B3>緵<EFBFBD><E7B7B5>-1
|
|
|
|
|
}
|
|
|
|
|
if (weight > MaxCost) return -2; // <20><><EFBFBD><EFBFBD>-2<><32>ʾȨֵ<C8A8><D6B5><EFBFBD><EFBFBD>
|
|
|
|
|
if (v1 == v2) return -3; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD>
|
|
|
|
|
int i = insert_edge_do(v1, v2, weight);
|
|
|
|
|
if (i == -4) return i; // <20><><EFBFBD>Ѵ<EFBFBD><D1B4><EFBFBD>
|
|
|
|
|
insert_edge_do(v2, v1, weight);
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
int Graph_List::delete_edge(int v2, int v1) {
|
|
|
|
|
if (v1 > graphsize - 1 || v2 > graphsize - 1 || v1 < 0 || v2 < 0) {
|
|
|
|
|
return -1; // Ԫ<>س<EFBFBD><D8B3><EFBFBD>
|
|
|
|
|
}
|
|
|
|
|
if (v1 == v2) return -1;
|
|
|
|
|
int i = delete_edge_do(v1, v2);
|
|
|
|
|
if (i == -1) return i;
|
|
|
|
|
delete_edge_do(v2, v1);
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
int Graph_List::delete_vertex(const int& v) {
|
|
|
|
|
if (v > graphsize - 1 || v < 0) return -1; // Ԫ<>س<EFBFBD><D8B3><EFBFBD>
|
|
|
|
|
for (int i = 0; i < graphsize; i++) delete_edge(i, v); // ɾ<><C9BE><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD>б<EFBFBD>
|
|
|
|
|
for (int j = v; j <= graphsize - 2; j++) head[j] = head[j + 1]; // <20>Ѹö<D1B8><C3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD>ǰŲһ<C5B2><D2BB>λ<EFBFBD><CEBB>
|
|
|
|
|
graphsize--;
|
|
|
|
|
for (int k = 0; k < graphsize - 1; k++) {
|
|
|
|
|
Edge* p = head[k].get_adjacent();
|
|
|
|
|
while (p) {
|
|
|
|
|
if (p->get_VerAdj() > v) p->get_VerAdj()--;
|
|
|
|
|
p = p->get_link();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
int Graph_List::modify_vertex(int v, std::string _n, std::string _des, int& _m, int& _x, int& _y) {
|
|
|
|
|
if (v < 0 || v > number_of_vertices() - 1) return -1;
|
|
|
|
|
head[v].get_VerName() = _n;
|
|
|
|
|
head[v].get_Description() = _des;
|
|
|
|
|
head[v].get_mark() = _m;
|
|
|
|
|
head[v].get_x() = _x;
|
|
|
|
|
head[v].get_y() = _y;
|
|
|
|
|
head[v].get_x() += LEFTBORDER;
|
|
|
|
|
head[v].get_y() += TOPBORDER;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
int Graph_List::dshortest_path(const int v, int*& path) {
|
|
|
|
|
int n = graphsize;
|
|
|
|
|
int* s = new int[n]; // <20>ýڵ<C3BD><DAB5>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ʹ<EFBFBD>
|
|
|
|
|
int* dist = new int[n]; // <20><><EFBFBD>ŵ<EFBFBD>ǰ<EFBFBD>ڵ㵽<DAB5><E3B5BD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̳<EFBFBD><CCB3><EFBFBD>
|
|
|
|
|
int i = 0, temp = 0;
|
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
|
s[i] = 0; // δ<><CEB4><EFBFBD>ʽڵ<CABD>Ϊ0
|
|
|
|
|
dist[i] = MaxCost * graphsize * (graphsize - 1) / 2; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
path[i] = -1; // ·<><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
}
|
|
|
|
|
int u = v;
|
|
|
|
|
Edge* p = NULL;
|
|
|
|
|
dist[u] = 0;
|
|
|
|
|
s[u] = 1;
|
|
|
|
|
path[u] = u;
|
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
|
|
s[u] = 1;
|
|
|
|
|
p = head[u].get_adjacent();
|
|
|
|
|
while (p) {
|
|
|
|
|
temp = p->get_VerAdj();
|
|
|
|
|
if (dist[u] + p->get_cost() < dist[temp]) {
|
|
|
|
|
dist[temp] = dist[u] + p->get_cost();
|
|
|
|
|
path[temp] = u;
|
|
|
|
|
}
|
|
|
|
|
p = p->get_link();
|
|
|
|
|
}
|
|
|
|
|
temp = MaxCost * graphsize * (graphsize - 1) / 2;
|
|
|
|
|
for (int j = 0; j < n; j++) {
|
|
|
|
|
if (s[j] == 0 && dist[j] < temp) {
|
|
|
|
|
temp = dist[j];
|
|
|
|
|
u = j;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
delete[]s;
|
|
|
|
|
delete[]dist;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
int Graph_List::dlongest_path(const int v, int*& path) {
|
|
|
|
|
int n = graphsize;
|
|
|
|
|
int* visit = new int[n]; // <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ʹ<EFBFBD>
|
|
|
|
|
int* dist = new int[n]; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
int i = 0, temp = 0;
|
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
|
|
visit[i] = 0;
|
|
|
|
|
dist[i] = 0; // <20>Ͻ<EFBFBD>˹<EFBFBD><CBB9><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD>
|
|
|
|
|
path[i] = -1; // <20><>·<EFBFBD><C2B7>
|
|
|
|
|
}
|
|
|
|
|
int u = v;
|
|
|
|
|
Edge* p = NULL;
|
|
|
|
|
dist[u] = 0;
|
|
|
|
|
visit[u] = 1;
|
|
|
|
|
path[u] = u;
|
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
|
|
visit[u] = 1;
|
|
|
|
|
p = head[u].get_adjacent();
|
|
|
|
|
while (p) {
|
|
|
|
|
temp = p->get_VerAdj();
|
|
|
|
|
if (dist[u] + p->get_cost() > dist[temp]) {
|
|
|
|
|
dist[temp] = dist[u] + p->get_cost();
|
|
|
|
|
path[temp] = u;
|
|
|
|
|
}
|
|
|
|
|
p = p->get_link();
|
|
|
|
|
}
|
|
|
|
|
int t = 0;
|
|
|
|
|
for (int j = 0; j < n; j++) {
|
|
|
|
|
if (dist[j] > t && visit[j] == 0) {
|
|
|
|
|
t = dist[j];
|
|
|
|
|
u = j;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
delete[]visit;
|
|
|
|
|
delete[]dist;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|