掌握无向图的创建、遍历方法。
class graph {
public:
graph(int n, int e) {
node = n;
edge = e;
a = new int *[n+1];
for(int i = 1; i <= n; i++) {
a[i] = new int[n+1];
for(int j = 1; j <= n; j++) {
a[i][j] = noEdge;
}
}
}
private:
int node;
int edge;
int ** a;
int noEdge = 0;
};
因为是无向图,所以边是相互的。
void insertEdge(int start, int end, int weight) {
a[start][end] = weight;
a[end][start] = weight;
}
用队列,因为要求输出逗号,所以写的比较复杂。
void BFS(int v, int reach[], int label) {
bool flag = false;
queue<int> q;
reach[v] = label;
q.push(v);
while(!q.empty()) {
int w = q.front();
q.pop();
if(flag == false) {
flag = true;
cout<<w;
} else cout<<","<<w;
for(int i = 1; i <= node; i++) {
if(a[w][i] != 0 && reach[i] != label) {
q.push(i);
reach[i] = label;
}
}
}
}
简化后:无输出。
void BFS(int v, int reach[], int label) {
queue<int> q;
reach[v] = label;
q.push(v);
while(!q.empty()) {
int w = q.front();
q.pop();
for(int i = 1; i <= node; i++) {
//当有这条边&没到达过才会将其入队
if(a[w][i] != 0 && reach[i] != label) {
q.push(i);
reach[i] = label;
}
}
}
}
用堆栈,递归调用的思想。
void DFS(int v, int reach[], int label) {
reach[v] = label;
if(fl == false) {
cout<<v;
fl = true;
} else {
cout<<","<<v;
}
for(int i = 1; i <= node; i++) {
if(a[v][i] != 0 && reach[i] != label) {
DFS(i,reach,label);
}
}
}
同样,简化后代码:
因为要求从小的数开始输出,所以没有“恢复”
void DFS(int v, int reach[], int label) {
reach[v] = label;
for(int i = 1; i <= node; i++) {
if(a[v][i] != 0 && reach[i] != label) {
DFS(i,reach,label);
}
}
}
加上“恢复”:
void DFS(int v, int reach[], int label) {
reach[v] = label;
for(int i = 1; i <= node; i++) {
if(a[v][i] != 0 && reach[i] != label) {
DFS(i,reach,label);
reach[i] = 0;
}
}
}
我的思路是:
int pathLength(int start) {
int reach[100] = {0};
int rea[100] = {0};
bfs(1,reach,2);
if(reach[node] != 2) return 0;
else {
dfs(1,rea,2,0);
return crr[0];
}
}
void dfs(int v, int reach[], int label, int weight) {
reach[1] = label;
for(int i = 1; i <= node; i++) {
if(a[v][i] != 0 && reach[i] != label) {
weight += a[v][i];
//到达终点就退出
if(i == node) {
//与之前的权重比较,小就保留,大就舍弃
if(weight < crr[0]) crr[0] = weight;
return;
} else {
reach[i] = label;
dfs(i,reach,label,weight);
reach[i] = 0;
//一定要减掉,不仅要恢复标记,还要恢复权重,否则结果会偏大
weight -= a[v][i];
}
}
}
}
void bfs(int v, int reach[], int label) {
queue<int> q;
reach[v] = label;
q.push(v);
while(!q.empty()) {
int w = q.front();
q.pop();
for(int i = 1; i <= node; i++) {
if(a[w][i] != 0 && reach[i] != label) {
q.push(i);
reach[i] = label;
}
}
}
}
输入全都是字符串,属实是绷不住了,处理麻烦死了 。
直接看下面完整代码叭。。
5,8
1,2,10
1,3,50
1,5,100
2,3,200
2,4,30
3,4,290
3,5,250
4,5,280
1,2,3,5,4
1,2,3,4,5
100
#include
using namespace std;
const int M = 100;
int arr[M];
int brr[M];
int crr[M];
int path[M];
bool fl = false;
class graph {
public:
graph(int n, int e) {
node = n;
edge = e;
a = new int *[n+1];
for(int i = 1; i <= n; i++) {
a[i] = new int[n+1];
for(int j = 1; j <= n; j++) {
a[i][j] = noEdge;
}
}
}
void insertEdge(int start, int end, int weight) {
a[start][end] = weight;
a[end][start] = weight;
}
void BFS(int v, int reach[], int label) {
bool flag = false;
queue<int> q;
reach[v] = label;
q.push(v);
while(!q.empty()) {
int w = q.front();
q.pop();
if(flag == false) {
flag = true;
cout<<w;
} else cout<<","<<w;
for(int i = 1; i <= node; i++) {
if(a[w][i] != 0 && reach[i] != label) {
q.push(i);
reach[i] = label;
}
}
}
}
void DFS(int v, int reach[], int label) {
reach[v] = label;
if(fl == false) {
cout<<v;
fl = true;
} else {
cout<<","<<v;
}
for(int i = 1; i <= node; i++) {
if(a[v][i] != 0 && reach[i] != label) {
DFS(i,reach,label);
}
}
}
int pathLength(int start) {
int reach[100] = {0};
int rea[100] = {0};
bfs(1,reach,2);
if(reach[node] != 2) return 0;
else {
dfs(1,rea,2,0);
return crr[0];
}
}
void dfs(int v, int reach[], int label, int weight) {
reach[1] = label;
for(int i = 1; i <= node; i++) {
if(a[v][i] != 0 && reach[i] != label) {
weight += a[v][i];
if(i == node) {
if(weight < crr[0]) crr[0] = weight;
return;
} else {
reach[i] = label;
dfs(i,reach,label,weight);
reach[i] = 0;
weight -= a[v][i];
}
}
}
}
void bfs(int v, int reach[], int label) {
queue<int> q;
reach[v] = label;
q.push(v);
while(!q.empty()) {
int w = q.front();
q.pop();
for(int i = 1; i <= node; i++) {
if(a[w][i] != 0 && reach[i] != label) {
q.push(i);
reach[i] = label;
}
}
}
}
private:
int node;
int edge;
int ** a;
int noEdge = 0;
};
int main() {
cout<<"Input"<<endl;
string n = "",m = "";
string S;
cin>>S;
int temp;
for(int i = 0; i < S.length(); i++) {
if(S.at(i) == ',') {
temp = i;
break;
}
}
for(int p = 0; p < temp; p++) {
n += S.at(p);
}
for(int p = temp + 1; p < S.length(); p++) {
m += S.at(p);
}
int num1 = stoi(n);
int num2 = stoi(m);
graph g(num1,num2);
for(int i = 0; i < num2; i++) {
string s;
cin>>s;
int fir = 0;
int sec = 0;
for(int j = 0; j < s.length(); j++) {
if(s.at(j) == ',' && fir == 0) fir = j;
else if(s.at(j) == ',' && fir != 0) {
sec = j;
break;
}
}
string s1 = "";
string s2 = "";
string s3 = "";
for(int p = 0; p < fir; p++) {
s1 += s.at(p);
}
for(int q = fir + 1; q < sec; q++) {
s2 += s.at(q);
}
for(int o = sec + 1; o < s.length(); o++) {
s3 += s.at(o);
}
g.insertEdge(stoi(s1), stoi(s2), stoi(s3));
}
cout<<"Output"<<endl;
g.BFS(1,arr,2);
cout<<endl;
g.DFS(1,brr,2);
cout<<endl;
//让第0组权重无限大,其他就都会比他小了(
crr[0] = 10000000;
int ans = g.pathLength(1);
cout<<ans<<endl;
cout<<"End";
return 0;
}