首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >通过寻找顶点和边从连通图中移除圈

通过寻找顶点和边从连通图中移除圈
EN

Stack Overflow用户
提问于 2016-01-16 05:10:17
回答 2查看 1.6K关注 0票数 2

如何从这样的图形中删除所有循环?所有的边长是一个,所有的边都是垂直的或水平的。图是连通的。

我想要计算必须删除的最小边数,这样图才能不包含循环。

如果包含示例代码(最好是C++、C或Java),这将是非常有帮助的。

更新:显然我必须找到顶点和边的数目。我给出了一组指令,如(向下、左、上、下、左、左、上、下)。从坐标平面上的(0,0)开始,向指定的方向移动一个单元。这将创建一个图表。我如何从这组指令中得到顶点和边的数目?

EN

Stack Overflow用户

发布于 2016-02-22 15:23:40

要根据方向(上、下、左、右)绘制一个图,并对顶点、边(并由此派生的:基本循环)进行计数,您可以:

  • 记录当前x,y坐标--一个“海龟”;
  • 保留一组已访问的顶点,因此您只计算唯一的实例;
  • 对于边缘,或者更多的内存--高效地做同样的事情:看看最近的移动是否包括至少一个以前没有访问过的点,而不是前一个动作的相反点:如果是这样的话,把它算作边缘。

这里有一个JavaScript实现--作为奖励--还绘制了图表:

代码语言: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();
代码语言:javascript
运行
复制
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>

当您更改输入时,结果将实时更新。

票数 0
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34823742

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档