题目链接:
https://pintia.cn/problem-sets/994805342720868352/problems/994805523835109376
首先说下我踩到的一个坑:
for (int i = 0; i < RoadNum; i++) {
vector<int> temp = roadInfo.at(i); //这里绝对是深拷贝,所以不如新建一个数组简洁。
cin >> temp.at(0)>>temp.at(1)>>temp.at(2);
roadInfo.at(i) = temp; //这一步很必要,踩过坑
}
roadInfo是一个vector<vector<int>>类型的变量,我一位这是个浅拷贝,因为可以把roadInfo中第i-th元素赋值给temp,我就剩下点声明变量的力气。谁能像这是个深拷贝,太坑了。不管怎样,上面的代码加上最后一行是管用的。
代码结构
因为对C++不太熟悉,所以在编写面向对象C++遇到很多坑,但是没有上面说的奇葩。这里只是介绍我对带权邻接链表的构造,当然都是用的vector,一个算法我就不苛求小的效率了。
用JSON格式表示出来:
JSON在描述简单几个对象结构时,感觉非常清晰,也是我经常构造对象工具
Adjacent //邻接链表
{
vector<Node> nodes; //节点集合
Node{
int index; //节点编号
vector<Link> links; //与其他节点连接
Link{
int ni; //边端
int nj; //边端
int weight;//权重
}
}
}
这个东西就是一数据结构,无向图。
代码:
// MultiShortestPath.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
int MaxIndex=600;
class Link {
public:
int weight;
int ni;
int nj;
public:
Link(int ni, int nj, int weight) {
this->ni = ni;
this->nj = nj;
this->weight - weight;
}
Link(vector<int> info) {
this->ni = info.at(0);
this->nj = info.at(1);
this->weight = info.at(2);
}
bool isAbout(int one) {
if (one == ni || one == nj) {
return true;
}
else {
return false;
}
}
//toString
friend ostream &operator<<(ostream &output, const Link &link) {
cout << "{";
cout << link.ni << "," << link.nj << "," << link.weight<<"}"<<endl;
return output;
}
};
//nodes connection to
class Node {
public:
int index;
vector<Link> links;
public:
Node(int add,vector<Link> conn) {
index = add;
links = conn;
}
Node(int add) {
this->index = add;
}
friend ostream &operator<<(ostream &output, const Node &node) {
cout << "{" << "\n"<< node.index<< "\n";
for (int i = 0; i < node.links.size(); i++) {
cout << node.links.at(i) << endl;
}
cout << "}";
return output;
}
/**
@Function:
Node need to be self-contained,remove its connections with the specified node
@parameter
int spec:specified node being disconnected with current node
**/
void cancelConnection(int spec) {
//a node can't disconnect with itself
if (this->index == spec) {
cout << "error";
return;
}
for (int i = 0; i < links.size(); i++) {
if (this->links.at(i).ni == spec || this->links.at(i).nj == spec) {
this->links.erase(links.begin()+i);
break;
}
}
}
};
//邻接矩阵
class Adjacent {
public:
//node index
vector<Node> information;
public:
//default constructor
Adjacent() {
}
/**
@Function
single constructor for 'Adjacent'
@Parameter
@int cityNum:
citys Number
@vector<vector<int>> road:
road infomation,vector<int> that's nested in outer vector has exactly three elements,
which is a raw "Link"
**/
Adjacent(int cityNum,vector<vector<int>> road) {
//so initially,information's struture is very simple,the i-th element stores the Node whose index is i
for (int i = 0; i < cityNum; i++) {
information.push_back(Node(i));
}
vector<int> roadtemp;
//add road infomation
for (int i = 0; i < road.size(); i++) {
roadtemp = road.at(i);
information.at(roadtemp.at(0)).links.push_back(Link(roadtemp));
information.at(roadtemp.at(1)).links.push_back(Link(roadtemp));
}
}
friend ostream &operator<<(ostream &output, const Adjacent &adjacent) {
cout << "{" << endl;
for (int i = 0; i < adjacent.information.size(); i++) {
cout << adjacent.information.at(i)<<endl;
}
cout << "}" << endl;
return output;
}
/**
@Function:
find the current index of the specified node in vector information
**/
int findNode(int index){
int temp=MaxIndex;
for (int i = 0; i < information.size(); i++) {
if (information.at(i).index == index) {
temp = i;
break;
}
}
if (temp == MaxIndex) {
cout << "error";
}
return temp;
}
/**
@Function
remove nodes and its connection
@Parameter
the nodes passed into this method are not required to be in order
**/
void compact(vector<int> loser) {
for (int current = 0; current < loser.size(); current++) {
//remove single Node in information
information.erase(information.begin()+findNode(loser.at(current)));
//disconnect all links who have connection with current Node
for (int i = 0; i < information.size(); i++) {
information.at(i).cancelConnection(loser.at(current));
}
}
}
};
class Graph {
public:
Adjacent data;
int rescuer;
int rescuee;
Graph() {
}
};
Graph Input(Graph emergency) {
int cityNum;
int RoadNum;
int rescuer;
int rescuee;
cin >> cityNum >> RoadNum >> rescuer >> rescuee;
vector<int> teams(cityNum,0);
int temp;
for (int i = 0; i < cityNum; i++) {
cin >> temp;
teams.at(i)=temp;
}
vector<int> road(3, INT_MAX);
vector<vector<int>> roadInfo;
for (int i = 0; i < RoadNum; i++) {
roadInfo.push_back(road);
}
for (int i = 0; i < RoadNum; i++) {
vector<int> temp = roadInfo.at(i); //这里绝对是深拷贝,所以不如新建一个数组简洁。
cin >> temp.at(0)>>temp.at(1)>>temp.at(2);
roadInfo.at(i) = temp; //这一步很必要,踩过坑
}
emergency.rescuer = rescuer;
emergency.rescuee = rescuee;
emergency.data = Adjacent(cityNum,roadInfo);
return emergency;
}
int main()
{
Graph emergency;
emergency = Input(emergency);
cout << emergency.data;
return 0;
}
输入:
5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1
输出:
{
{
0
{0,1,1}
{0,2,2}
{0,3,1}
}
{
1
{0,1,1}
{1,2,1}
}
{
2
{0,2,2}
{1,2,1}
{2,4,1}
}
{
3
{0,3,1}
{3,4,1}
}
{
4
{2,4,1}
{3,4,1}
}
}
待续~~