英文:
Minimum Edge required to connect a unconnected directed graph
问题
我正在尝试编写一个算法,该算法可以找到连接有向非连接图中所有起始顶点的所有节点所需添加的最少边数
```cpp
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
class Graph {
vector<vector<int>> vertices;
public:
Graph(int num_ver) {
vertices.resize(num_ver);
}
void addEdge(int ver1, int ver2) {
vertices[ver1].push_back(ver2);
}
vector<int>& getNeighbors(int ver) {
return vertices[ver];
}
int getVertices() {
return vertices.size();
}
};
void dfs(Graph& graph, int vertex, vector<bool>& visited) {
visited[vertex] = true;
vector<int>& neighbors = graph.getNeighbors(vertex);
for (int i = 0; i < neighbors.size(); i++) {
int n = neighbors[i];
if (!visited[n]) {
dfs(graph, n, visited);
}
}
}
int findMinEdges(Graph& graph) {
int num_vertices = graph.getVertices();
vector<bool> visited(num_vertices, false);
int edges = 0;
for (int i = 0; i < num_vertices; i++) {
if (!visited[i]) {
dfs(graph, i, visited);
edges++;
}
}
return (edges - 1);
}
int main() {
ifstream f("input.txt");
int vertices, edges, start;
f >> vertices >> edges >> start;
//cout << vertices << edges << start;
Graph g(vertices + 1);
int v1, v2;
for (int i = 0; i < edges; i ++) {
f >> v1 >> v2;
g.addEdge(v1, v2);
}
f.close();
int min_edges = findMinEdges(g);
cout << "Minimum number of edges to make the graph connected: " << min_edges << endl;
ofstream o("output.txt");
o << min_edges;
o.close();
return 0;
}
这段代码使用了一个简单的图数据结构和深度优先搜索算法来尝试实现此目标。我已经尝试在较小的输入上运行代码,它可以正常工作,但当输入规模增大时,它返回错误的答案。我已经尝试使用其他算法,例如Trajan的算法,但即使那个也没有对我起作用。
样本输入文件:
6 5 5
1 2
2 3
3 1
4 5
5 6
前3个数字代表总顶点数、总边数和起始顶点,接下来的行表示边(第一个数字是v1,第二个是v2)。
对于此示例,代码可以正常工作,但对于较大的输入则不行。我似乎无法理解问题出在哪里!
https://file.io/bHnJHoqSE3ji 包含输入文本文件。算法给出的输出是356,而预期输出是263。
英文:
I am trying to write an algorithm that finds the minimum number of edges that are required to be added to connect all nodes from the starting vertices in a directed unconnected graph
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
class Graph {
vector<vector<int>> vertices;
public:
Graph(int num_ver) {
vertices.resize(num_ver);
}
void addEdge(int ver1, int ver2) {
vertices[ver1].push_back(ver2);
}
vector<int>& getNeighbors(int ver) {
return vertices[ver];
}
int getVertices() {
return vertices.size();
}
};
void dfs(Graph& graph, int vertex, vector<bool>& visited) {
visited[vertex] = true;
vector<int>& neighbors = graph.getNeighbors(vertex);
for (int i = 0; i < neighbors.size(); i++) {
int n = neighbors[i];
if (!visited[n]) {
dfs(graph, n, visited);
}
}
}
int findMinEdges(Graph& graph) {
int num_vertices = graph.getVertices();
vector<bool> visited(num_vertices, false);
int edges = 0;
for (int i = 0; i < num_vertices; i++) {
if (!visited[i]) {
dfs(graph, i, visited);
edges++;
}
}
return (edges - 1);
}
int main() {
ifstream f("input.txt");
int vertices, edges, start;
f >> vertices >> edges >> start;
//cout << vertices << edges << start;'
Graph g(vertices + 1);
int v1, v2;
for (int i = 0; i < edges; i ++) {
f >> v1 >> v2;
g.addEdge(v1, v2);
}
f.close();
int min_edges = findMinEdges(g);
cout << "Minimum number of edges to make the graph connected: " << min_edges << endl;
ofstream o("output.txt");
o << min_edges;
o.close();
return 0;
}
The code uses a simple graph data structure and dfs algorithm to try to accomplish this. I have tried running the code on smaller inputs and it works but when the input size increases, it returns the wrong answer. I have tried using other algorithms i.e. Trajan's algorithm but even that has not worked for me.
A sample input file:
6 5 5
1 2
2 3
3 1
4 5
5 6
The first 3 numbers represent total vertices, total edges, starting vertex
and next line represent the edges (the first number is v1 and the second v2).
The code work fine for this but not for larger inputs. I dont seem to understand where the problem is!
https://file.io/bHnJHoqSE3ji contains the input text file. The output the algo is giving is 356 and the expected output is 263.
答案1
得分: 2
首先,似乎你的邻接表是以1为基础,而你的访问数组是以0为基础,有时你使用你的邻接表就好像它是以0为基础的。
其次,我注意到你根本没有使用变量“start”。然而,如果图看起来像这样:
2 <- 1
如果起始节点是2,那么答案是1。如果起始节点是1,那么答案是0。如果你的代码中没有使用“start”,那么你的算法几乎不可能正确。
英文:
First, it seems that your adjacency list is 1-based while your visit
array is 0-based, and you sometimes use your adjacency list as if it's 0-based.
Second, I noticed that you didn't use the variable start at all. However, what if the graph looks like this:
2 <- 1
If the start node is 2, then the answer is 1. If the start node is 1 then the answer is 0. If you didn't use start in your code, it's impossible that your algorithm is correct.
答案2
得分: 0
如@TYeung所指出,你忽略了使用起始顶点。如果你从指定的顶点开始,将会获得更好的结果:
int findMinEdges(Graph& graph, int start) {
int num_vertices = graph.getVertices();
vector<bool> visited(num_vertices, false);
dfs(graph, start, visited);
int edges = 0;
for (int i = 0; i < num_vertices; i++) {
if (!visited[i]) {
dfs(graph, i, visited);
edges++;
}
}
return (edges - 1);
}
然而,是否获得最小数量的边取决于输入顶点的顺序。
考虑这个图:
0 -> 1
2 -> 1
3 -> 1
3 -> 2
DFS起始点 | 未访问的顶点 | 边数 |
---|---|---|
0 | 2,3 | 0 |
2 | 3 | 1 |
3 | - | 2 |
现在以不同的顺序输入顶点:
0 -> 1
3 -> 1
3 -> 2
2 -> 1
DFS起始点 | 未访问的顶点 | 边数 |
---|---|---|
0 | 2,3 | 0 |
3 | - | 1 |
英文:
As @TYeung points out, you have missed using the start vertex. You will get better result if you do start from the specified vertex:
int findMinEdges(Graph& graph, int start) {
int num_vertices = graph.getVertices();
vector<bool> visited(num_vertices, false);
dfs(graph, start, visited);
int edges = 0;
for (int i = 0; i < num_vertices; i++) {
if (!visited[i]) {
dfs(graph, i, visited);
edges++;
}
}
return (edges - 1);
}
However, whether or not you get the minimum number of edges depends on the order of the input vertices.
Consider this graph
0 -> 1
2 -> 1
3 -> 1
3 -> 2
DFS start | unvisited | edges |
---|---|---|
0 | 2,3 | 0 |
2 | 3 | 1 |
3 | - | 2 |
Now input the vertices in a different order
0 -> 1
3 -> 1
3 -> 2
2 -> 1
DFS start | unvisited | edges |
---|---|---|
0 | 2,3 | 0 |
3 | - | 1 |
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论