【美團面試題】——圖遍歷

題目:

給定一個包含N個節點的連通圖,節點編號1到n。共有n-1條邊。從1號節點出發,問遍歷全部節點最短路程多少?node

數據輸入方式:共n行,第一行是節點個數。下面的n-1行每一行爲兩個正整數,表明互相連通的兩個節點。ios

!@#¥%:

題目沒有明確1號節點是否在圖的邊緣,也沒有提到圖的複雜度如何。spa

網上看了幾個別人的程序,但有的程序太過簡單,稍微複雜一點的圖結果就不對了。下來在VS裏編了下,沒有調用別的複雜的庫,只是用了 vector 。blog

我這個程序雖然能應對複雜一點的圖,但還不是能夠應對全部狀況,限制條件爲:ci

1)1號節點必須在圖的邊緣;get

2)分支深度不能大於1。以下圖,左面的分支爲 6-七、6-8,深度均爲1;右圖分支爲 6-七、6-8-9,深度爲1和2。it

程序(C++):

頭文件 map_gao.hio

#pragma once
#include<vector>
#include<iostream>class

using namespace std;
namespace gao{
class node {
public:
node() :used(false), num(0) {}
bool used; //是否已被cull
int num; //鏈接的節點數
vector<int> neigh; //鄰居節點序號
vector<int> getchild_id() { return neigh; }
//void add(int a,int b);
};stream

class Map {
public:
vector<node> nodes;

int distance;

bool checkNode(int id) {
if (nodes[id].num) return true; //非空
else return false;
}

void cull(int id); //裁剪指定節點邊
int computeTree(int rootId); //裁剪整個樹
void computeDistance(); //計算總路程
void print(); //打印節點和路程信息

};//end class Map

void Map::cull(int id) {
nodes[id].used = true;
vector<int> child_id;
child_id = nodes[id].getchild_id();
int idNum = child_id.size();
for (int i = 0; i < idNum; i++) {
vector<int> *childs;
childs = &nodes[child_id[i]].neigh;
for (vector<int>::iterator it = childs->begin(); it != childs->end();)
if (nodes[*it].used) {
it = childs->erase(it);
nodes[child_id[i]].num--;
}
else it++;
}
}

int Map::computeTree(int rootId) {
if (!checkNode(rootId)) return 0;
else {
cull(rootId);
node childs;
vector<int> child_id;
child_id = nodes[rootId].getchild_id();
int idNum = child_id.size();
for (int i = 0; i < idNum; i++)
computeTree(child_id[i]);
}
}

void Map::computeDistance() {
distance = 0;
for (int i = 1; i < nodes.size(); i++)
if (nodes[i].num) distance += nodes[i].num * 2 - 1;
}

void Map::print() {
cout << "總路程爲: " << distance << endl;
//for (int i = 1; i < nodes.size(); i++) {
// cout << "nodes[" << i << "].num: " << nodes[i].num << endl;
//}
}


}//end namespace gao

 

源文件 遍歷樹.cpp


#include"map_gao.h"

using namespace std;
using namespace gao;

void main() {
int N;
cin >> N;
vector<node> nodes;
nodes.resize(N+1);
int a, b;
for (int i = 0; i < N - 1; i++) {
cin >> a >> b;
nodes[a].neigh.push_back(b);
nodes[a].num++;
nodes[b].neigh.push_back(a);
nodes[b].num++;
}

Map map;
map.nodes = nodes;
int distance = 0;
int startId;
startId = 1; //從哪一個節點開始出發
map.computeTree(startId);
map.computeDistance();
distance += map.distance;
map.print();

getchar(); getchar();
}

 

結果:

4個節點(試題樣例),路徑爲 1-2-1-3-4:

8個節點,路徑爲1-2-3-2-4-5-6-5-7-5-8:

10個節點(對應上面那個10個點的圖),路徑爲1-2-3-4-5-6-7-6-8-6-9-10:

相關文章
相關標籤/搜索