- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在为过去的一门课准备一套习题我应该实现Bellman-Ford算法,以便从源代码s
,我必须找到以下内容:
如果无法从s
访问节点(输出为*
)
如果节点是可到达的,但是是负循环的一部分,因此没有最短路径(输出为-
)
否则,输出从s
到节点的最短路径
我已经编写了以下代码,但在未知的测试用例中失败了有人能帮我调试一下吗?
void relax_edges(vector <vector<int>> &adj,
vector <vector<int>> &cost,
vector<long long> &dis)
{
/*Takes input as adjacency list and relax all possible edges
*/
for (int i = 0; i < adj.size(); i++) {
for (int j = 0; j < adj[i].size(); j++) {
if (dis[i] < std::numeric_limits < long long > ::max()
&& dis[adj[i][j]] > dis[i] + cost[i][j]){
//std::cout<< adj[i][j]<<" "<<i<<"\n";
dis[adj[i][j]] = dis[i] + cost[i][j];
}
}
}
}
void bfs(vector<vector<int> > &adj, vector<int>& shortest, int s){
vector<int> seen (adj.size(), 0);
//seen[s] = 1;
queue<int> q;
q.push(s);
int t;
while(!q.empty()){
t = q.front();
q.pop();
if (seen[t] == 3)
break;
seen[t]+=1;
for(int i=0;i<adj[t].size();i++){
q.push(adj[t][i]);
}
}
for(int i=0;i<seen.size();i++)
if(seen[i]>=1)
shortest[i] = 0;
}
void shortest_paths(vector <vector<int>> &adj,
vector <vector<int>> &cost,
int s,
vector<long long> &dis,
vector<int> &reachable,
vector<int> &shortest) {
dis[s] = 0;// distance of s is 0 from s
int result;
for (int i = 0; i < adj.size() - 1; i++) { //Running Bellman Ford |V-1| times
relax_edges(adj, cost, dis);
}
vector<long long> distance2(dis.size(), 0);
for (int i = 0; i < distance2.size(); i++)
distance2[i] = dis[i];
relax_edges(adj, cost, distance2); // Running it |V|th time to identify negative cycle nodes
relax_edges(adj, cost, distance2); //Running it |V+1|th time to identify the first node of the negative cycle.
for(int i=0;i<distance2.size();i++){
//std::cout<<distance2[i]<<" "<<dis[i]<<"\n";
if(distance2[i]!=dis[i]){
bfs(adj, shortest, i);
shortest[i] = 0;
}
if (dis[i] < std::numeric_limits<long long>::max())
reachable[i] = 1;
}
}
最佳答案
我可以为您提供一个实现失败的示例。我还将描述这个问题的解决方案。
在运行relax_edges
|V| - 1
次之后,假设没有负循环,您可以从源中找到所有有效的最短路径。在放松了|V|
第二次之后,你可以知道是否有来自源的任何负循环(当任何最短距离减小时)。然而,这还不足以说明,对于每个节点来说,它是否位于可到达的负循环上。
看看下面的例子(INF
无限状态)。
正如你所看到的,在第次弛豫之后,我们可以说有一个负循环可以从源(节点3)到达。我们知道,因为有些节点(|V|
和2
)的源最短路径刚刚减少。然而,在两次额外的放松(如在您的实现中)之后,我们仍然不知道节点3
处于负循环。它离放射源的最短距离仍然和放松一样。
请注意以下几点。如果一个节点位于某个负周期上,那么它也最多位于长度为负的周期上。对于简单图和多重图,不管是什么情况,都是这样因此,不要在算法的第二部分运行0
一次或两次,而是应该运行|V| - 1
次这样可以确保每个节点都有可能遍历包含它的整个负循环。在这些|V|
附加松弛之后,您可以将得到的最短距离与第一次relax_edges
松弛所得到的最短距离进行比较。如果任何节点的最短距离较低,则可以确定该节点处于可从源访问的负循环上。
当然,所提供的解决方案并没有增加仍然是O的时间复杂度。唯一的缺点是常数较高。
在问题陈述中,您还提到如果存在的话,您需要返回最短路径。但是,我在您提供的代码中看不到它的相关部分。如果这也是一个缺失的东西,那么只要在松弛期间更新距离时记住节点的前一个节点更新前置任务的一个简单好例子,您可以在Wikipedia上找到。如果每个节点都有一个最短路径存在的前驱,则可以沿着路径向后走直到到达源。
编辑:
@ead显示我已经把要求“2”太字面化了,所以我正在改进我的答案。我提出的算法可以判断每个节点是否是可以从源到达的负循环的一部分。但是,可能有一个节点本身不是任何负循环的一部分,但是您可以从一个可以从源到达的负循环到达该节点因此,假设存在某个节点的最短路径,则必须确保它不能从源到达的任何负周期到达。
正如@ead所提出的,一个非常合理的解决方案是从所有节点运行图搜索(dfs或bfs),这些节点在第次松弛期间被检测为负循环的一部分。例如,无论何时执行|V|
,都会将节点|V|
添加到队列中。然后,可以使用队列中已存在的多个启动节点运行单个bfs。在此bfs期间访问的每个节点都是负循环的一部分,可从源访问,因此没有到它的最短路径。
编辑2:
使用bfs的方法通常是正确的,但我认为您的实现是错误的。我看不出检查是否|V| - 1
的意义您只需要记住,对于每个节点,在图搜索期间是否访问过。等价地,每当每个节点被推送到队列时,都可以将其标记为|V|
。以下是bfs的固定版本:
void bfs(vector<vector<int>>& adj, vector<int>& shortest, int s) {
vector<int> seen(adj.size(), 0);
queue<int> q;
q.push(s);
seen[s] = 1;
while (!q.empty()) {
int t = q.front();
q.pop();
for (int i = 0; i < adj[t].size(); ++i) {
if (!seen[adj[t][i]]) {
q.push(adj[t][i]);
seen[adj[t][i]] = 1;
}
}
}
for (int i = 0; i < seen.size(); ++i) {
if (seen[i] > 0) {
shortest[i] = 0;
}
}
}
shortest[i] = 0
函数中创建队列,并将满足
i
的每个节点推送到队列中。然后您只需要使用初始化的队列运行一次bfs。
关于algorithm - Bellman Ford算法在未知测试案例中失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41690418/
我有一个交叉表函数,我过去曾多次成功使用它,但现在它在最后转储所有数据,而不是将其旋转到输出表中。它似乎无法找到交叉表。我通过以下方式对其进行了研究; 如果 tablefunc 不存在则创建扩展; -
表1(客户表) Id, CustomerId, IsKnownCustomer,phonemacaddress 1, 空 0 00:9a:34:cf:a4 2, 004024 1 00:6f:64:c
知道为什么我总是收到这个烦人且无用的错误代码/描述吗? Failed to pull image myapidemodocker.azurecr.io/apidemo:v4.0: rpc error:
我正在进行 PHP 登录,并且之前可以正常工作,但我尝试使用户名功能不区分大小写,但此后代码一直无法正常工作。我删除了我添加的所有内容,以尝试使其不区分大小写,即 strtolower()。页面上显示
有人会帮助我提供有关此错误的任何可能信息吗?原因?登录?在哪里寻找/开始? Cannot use output buffering in output buffering display handl
我已经添加了这样的脚本 我在我的 test.js 中做了这个 var app = angular.module('MyApp', ['ngRoute']).config
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 8 年前。 Improve this qu
我有这个sql语句: selectAllUsersByCriteria = 连接.prepareStatement( “从用户那里选择*?=?” ); 下面的方法运行该语句: public Array
我有一个白色的 EditText,在 Android 3.1 及更高版本中,光标不显示(因为它也是白色的)。有关信息,我使用 android:background="@android:drawable
我正在尝试使用 Keras 实现深度学习模型。但是我有一个未知形状实现的问题。我一直在寻找类似的错误,但没有找到。 这是我的代码。 Xhome = dataset[:,32:62] Xaway = d
关注此introduction可以通过导入命名空间 System.Xml 来使用 XMLReader 类。在我的 Visual Studio 项目中,我使用 .NET 4.0,但 System.Xml
我有一个动态链接库的程序。该程序将函数指针传递给该库以执行。 但是 ubsan(Undefined Behavior Sanitizer)指定指针位于错误的函数类型上。那只会发生 如果回调函数有一个类
我正在尝试在我的 Swift SpriteKit 应用程序中使用 AVAudioSession。我遇到了奇怪的“未声明类型”问题。例如…… import AVFoundation var audioS
如果在编译期间(在实际编译和运行程序之前)其参数之一的值已知/未知,如何专门化模板函数? 我还不知道怎么做。 想法 1: #include #include int main(void){
我看到一些人的代码是这样的: while (!(baseType == typeof(Object))) { .... baseType = baseType.BaseType;
我正在尝试使用 GoColly 框架获取所有 HREF 链接,但是只允许任何域的 url 为根 URL 或子域(否路径)。我已经注释掉了我的 REGEXP。文件扩展名没有事情。我只是在“/”之后不想要
我有一个包含多个实体的数据库,特别是 Book 和 User。它们之间存在这样的 ManyToMany 关系: 书: @Entity @Table(name = "Books") public cla
如果我将范围的初始部分设置为 Range("A:A"),如何确保将整行传递给排序? 数据 id、fname、mname、lname、后缀、状态、位置、时区 通过在 id 中搜索起点和终点来选择范围。
我对kubernetes很陌生,而对于docker来说就不那么多了。 我一直在研究示例,但是我对自动缩放器(似乎无法缩放)感到困惑。 我在这里通过示例https://kubernetes.io/doc
我在 ChildWindow 中使用 SL Toolkit 5 中的 BusyIndicator 控件。 在某些解决方案中,它可以工作,但在其他解决方案中,使用完全相同的代码(至少看起来),我在运
我是一名优秀的程序员,十分优秀!