You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

303 lines
7.7 KiB

#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;
}