我想在有向图中找到顶点 1 和顶点 n 之间的路径数。该图包含循环。如果顶点 1 和顶点 n 之间的任何路径有循环,则结果应为“INFINITE PATHS”,否则为路径数。这是我尝试过的。
1)我修改了DFS算法,它从节点1开始,所有节点最初都是白色的。
2) 如果访问到一个灰色节点,则说明存在环路。
3)记录访问过的顶点的路径数组用于回溯循环中的节点。
4) 对于循环中的每个节点,未修改的 DFS 用于从该节点搜索第 n 个顶点。
5) 如果 DFS 从任何一个节点成功,则在顶点 1 和顶点 n 之间的路径中存在循环,因此它返回否则算法继续计算路径数。
C++实现
#include <stdio.h>
#include <malloc.h>
#include <vector>
#include <algorithm>
#define WHITE 0
#define GRAY 1
#define BLACK 2
using namespace std;
typedef struct vertexstruct{
int color;
vector<int> edgelist;
}vertex;
int ordinarydfs(int v,vertex *vertices,int numvertices){
if(v == numvertices){
return 1;
}
if(vertices[v].color == WHITE){
vertices[v].color = GRAY;
for(int i=0;i<vertices[v].edgelist.size();i++){
int x = ordinarydfs(vertices[v].edgelist[i],vertices,numvertices);
if(x ==1) return 1;
}
vertices[v].color = BLACK;
}
return 0;
}
int checkcycle(int v,vector<int>path,vertex *vertices,int numvertices){
vector<int>::iterator it;
vector<int>::iterator x;
it = find (path.begin(), path.end(), v);
for(x =it;x<path.end();x++)
vertices[*x].color = WHITE;
for(x =it;x<path.end();x++){
if(ordinarydfs(*x,vertices,numvertices))
return 1;
}
for(x =it;x<path.end();x++)
vertices[*x].color = GRAY;
return 0;
}
long dfs(int v,vertex *vertices,int numvertices,vector<int> path){
long paths = 0;
if(v == numvertices){
return 1;
}
if(vertices[v].color == GRAY) {
if(checkcycle(v,path,vertices,numvertices)) return -1;
}
if(vertices[v].color == WHITE){
vertices[v].color = GRAY;
path.push_back(v);
for(int i=0;i<vertices[v].edgelist.size();i++){
long x = dfs(vertices[v].edgelist[i],vertices,numvertices,path);
vertices[vertices[v].edgelist[i]].color = WHITE;
if(x == -1) return -1;
paths += x;
}
vertices[v].color = BLACK;
}
return paths % 1000000000;
}
void numpaths(int numvertices,int numedges,vertex *vertices){
vector<int> path;
long numpaths = 0;
numpaths = dfs(1,vertices,numvertices,path);
if(numpaths == -1)
printf("INFINITE PATHS\n");
else
printf("%ld\n",numpaths);
}
int main(){
int edgecount=0;
int numverts,numedges;
fscanf(stdin,"%d %d",&numverts,&numedges);
vertex verts[numverts+1];
for(int i =1;i<=numverts;i++)
verts[i].color = WHITE;
edgecount = 0;
int a,b;
while(edgecount < numedges){
scanf("%d %d",&a,&b);
verts[a].edgelist.push_back(b);
edgecount++;
}
numpaths(numverts,numedges,verts);
}
该算法对于大图来说太慢了。这个问题有正确的方法吗?分享你的意见。谢谢。
最佳答案
一种完全不同的方法是将图形表示为邻接矩阵 A[i][j]=1 如果 (i,j) 是边,否则为 0。然后 A^i[s][t] 计算从 s 到 t 的长度为 i 的路径数(这可以通过归纳法证明。想想 A^2 代表什么)。求和 A[s][t] 的 1..|V| 次方,得到所有可能的长度不超过 |V| 的路径。要检查是否存在循环,请查看(通过再次乘以矩阵)是否有长度为 |V|+1,...,2|V| 的路径存在。
这有帮助吗?
关于c++ - 有向循环图中两个节点之间的路径数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9630375/
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee
我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行
我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是: