我们如何修改以下DFS算法,以便它打印出来自起始节点的至少两条路径可访问的所有节点?
DFS(G,s):
foreach v in V do
color[v] <- white; p[v] <- nil
DFS-Visit(s)
DFS-Visit(u)
color[u] <- grey
foreach v in Adj[u] do
if color[v] = white then
p[v] = u; DFS-Visit(v)
color[u] <- black
E.g。如果图形是树,则不会打印任何节点。如果图形是循环,则将打印所有节点。
答案 0 :(得分:1)
尽管可以通过运行BFS而不是DFS轻松实现,但也可以通过运行 DFS两次来实现。
在第一次时,在访问顶点u
时,我们希望标记v
中Adj[u]
或gray
中的每个black
或special
。这意味着此顶点之前已被访问过,这意味着它至少有两个路径。我们将通过向顶点添加另一个字段来实现此目的,我们将其命名为DFS(G,s):
foreach v in V do
color[v] <- white; parent[v] <- nil; special[v] <- false
DFS-Visit(s)
DFS-Visit(u)
color[u] <- grey
foreach v in Adj[u] do
if color[v] = white then
parent[v] = u; DFS-Visit(v)
if color[v] = gray or color[v] = black
special[v] <- true
color[u] <- black
。
v
现在我们知道至少有两条路径可以访问special[v] == true
的每个顶点special
。
但这还不够 - 如果你想到一个循环,我们只会将我们开始的顶点标记为special
。这就是我们需要另一次DFS运行的原因。
因此,我们还要标记具有已经标记为DFS(G,s):
foreach v in V do
color[v] <- white; parent[v] <- nil
DFS-Visit(s)
DFS-Visit(u)
color[u] <- grey
foreach v in Adj[u] do
if special[u] = true
special[v] = true
if color[v] = white then
parent[v] = u; DFS-Visit(v)
color[u] <- black
的顶点的路径的所有顶点。我们可以通过运行另一个DFS :
v
最后,您可以打印具有special[v] == true
。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Tooling.Connector;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int choice;
CrmServiceClient crmConn = new CrmServiceClient(ConfigurationManager.ConnectionStrings["CRM"].ConnectionString);
IOrganizationService crmService = crmConn.OrganizationServiceProxy;
Entity acc = new Entity("account");
String account_name;
Console.WriteLine("Press 1 to Create a new account or Press 2 to view list of available accounts.");
choice = Convert.ToInt32(Console.ReadLine());
switch (choice)
{
case 1:
Console.WriteLine("Enter Name of Account to Create ?");
account_name = Console.ReadLine();
acc["name"] = account_name;
crmService.Create(acc);
Console.WriteLine("*****An account with name {0} is created successfully*****", account_name);
Console.WriteLine();
Console.WriteLine("Press any key to exit..");
Console.ReadKey();
break;
case 2:
//code to display list of all account names in CRM.
Console.ReadKey();
break;
default:
Console.WriteLine("Wrong input...");
Console.ReadKey();
break;
}
}
}
}
答案 1 :(得分:1)
第一步是写下我们可以想到的与我们正在寻找的属性相关的所有规则:从存在节点的s中存在多个不同的路径。
对于诸如s-> a,s-> b,a-> c,b-> c,c-> d的情况,我们需要条件1,以便打印c。对于像s - &gt;这样的情况,我们需要条件2。 x - &gt; y - &gt; s,打印出s。我们需要条件三,以便例如在上述情况下,打印d,x和y。条件4表明这些条件已足够。
我们可以通过更改我们的&#34;转身&#34;来修改DFS。条件。而不是&#34;转身&#34;当我们看到我们已经访问过的节点时,我们只是改变状态;现在我们不是寻找看不见的节点,而是从这个节点做一个DFS,用于我们以前见过的那些节点。在这个元DFS期间,如果我们看到之前已经看过两次,我们会回头;如果我们看到一个我们以前看不到的东西,我们会将其标记为不止一次,并继续前进。元DFS完成后,我们将返回原始DFS。因此节点有三个条件,我们有两个状态可以跟踪。条件是:
状态是:
以下是我们处理6种可能情况的方法:
规则1和2需要行为2.行为4和5是规则3所需要的。行为1,3和6耗尽了我们的其他可能性,并确保在这些情况下规则4成立。