如何从这样的图表中删除所有周期?所有边长均为1,所有边均为垂直或水平。图表已连接。
我想计算必须删除的最小边数,以使图形不包含循环。
如果您包含示例代码(最好是C ++,C或Java),那将非常有用。
更新:显然我必须找到顶点和边的数量。 我遇到的问题给出了一组指令,如(向下,向左,向上,向下,向左,向左,向上,向下)。从坐标平面(0,0)开始,沿指定方向移动一个单位。这将创建一个图表。如何从这组指令中获取顶点和边的数量?
答案 0 :(得分:2)
由于图表是连接的,如果你写的那个点是
计算需要移除的最小边数,以使图形不包含循环
那么你真的不需要编写算法。众所周知,删除循环的结果是树,并且所有树都具有相同数量的边(顶点数减1)。
如果要实际枚举剩余边(或删除的边),则可以使用DFS(深度优先搜索)。特别是,在output of DFS中,您只需保留标记为“树边”的内容。
虽然有DFS的C ++库,但它们可能不会以这种方式枚举边缘,并且可能更容易自己编写代码。如您所见,pseudocode非常简单。
答案 1 :(得分:0)
要根据方向(向上,向下,向左,向右)绘制图形,并保持顶点,边缘的计数(并从中得出:基本周期),您可以:
这是一个JavaScript实现 - 作为奖励 - 也绘制了图表:
function countEdgesAndVertices(directions, callback) {
var turtle = [0, 0],
vertices = {},
revisit = false,
edgeCount = 0,
delta = {l: [-1, 0], r: [1, 0], u: [0, -1], d: [0, 1]},
opposite = {l: 'r', r: 'l', u: 'd', d: 'u'},
oppositeDir = '';
vertices[turtle.join(',')] = true;
directions.split('').forEach(function(dir) {
if (!delta[dir]) return; // ignore invalid characters
// Move turtle in given direction
turtle[0] += delta[dir][0];
turtle[1] += delta[dir][1];
// Call caller's callback function with this vertex
if (callback) callback(turtle);
vertexId = turtle.join(',');
// If this created a new edge, count it
if (!vertices[vertexId] || !revisit && dir != oppositeDir) edgeCount++;
// Remember whether we were here before
revisit = vertices[vertexId];
// Add vertice to set
vertices[vertexId] = true;
// Remember direction, so we wont count a move
// in the opposite direction as a new edge
oppositeDir = opposite[dir];
});
return {
edges: edgeCount,
vertices: Object.keys(vertices).length
}
}
// IO
var input = document.querySelector('input');
var output = document.querySelector('span');
var canvas = document.querySelector('canvas');
var canvasContext;
// Drawing routines
function canvasDrawTo(vertex) {
var scale = canvas.height/10;
console.log('line to ', vertex[0],vertex[1]);
canvasContext.lineTo(vertex[0]*scale,vertex[1]*scale);
canvasContext.stroke();
}
function canvasClear(vertex) {
canvas.width = canvas.width; // not nice, but this resets canvas
canvasContext = canvas.getContext("2d");
canvasContext.translate(canvas.width/2,canvas.height/2);
canvasContext.beginPath();
canvasContext.lineTo(0,0);
}
function update() {
canvasClear();
var result = countEdgesAndVertices(input.value, canvasDrawTo);
output.textContent = 'Vertices: ' + result.vertices +
'; Edges: ' + result.edges +
'; Non-divisable cycles: ' + (result.edges - result.vertices + 1);
};
// call update on any input change:
input.oninput = update;
// call update on load
update();

String of directions (u=up,d=down,l=left,r=right):<br>
<input type="text" size="40" value="uldrdddurulurdrdluurdur"><br>
Result: <span></span><br>
<canvas width="200" height="100"></canvas>
&#13;
当您更改输入时,结果会实时更新。