我已针对上述问题编写了以下代码。
我通过选择起始节点并从中执行DFS来检查Graph是否已连接。并检查Euler路径和巡视的条件,代码将是count = 2或0.它适用于所有给定的测试用例。但是在提交时得到错误答案
#include<iostream>
#include<cmath>
#include<list>
#include<string>
#include<stack>
using namespace std;
class Graph
{
int V;
list<int> *adj;
int *in;
public:
Graph(int v)
{
this->V=v;
this->adj=new list<int>[V];
this->in=new int[V];
for(int i=0;i<V;i++)
{
in[i]=0;
}
}
void addEdge(int src,int des)
{
adj[src].push_back(des);
in[des]=in[des]+1;
}
void DFSUtil(bool visited[],int v)
{
stack<int> s;
s.push(v);
visited[v]=true; //mark v as visited;
while (!s.empty())
{
int top=s.top();
s.pop();
list<int> :: iterator it;
for(it=adj[top].begin();it!=adj[top].end();it++)
{
if(!visited[*it])
{
visited[*it]=true;
s.push(*it);
}
}
}
}
/*void DFSUtil(bool visited[],int v)
{
visited[v]=true;
list<int> :: iterator it;
for(it=adj[v].begin();it!=adj[v].end();it++)
{
if(!visited[*it])
{
DFSUtil(visited,*it);
}
}
}*/
// Graph reverseGraph()
// {
// Graph g(V);
// for(int i=0;i<V;i++)
// {
// list<int> :: iterator it;
// for(it=adj[i].begin();it!=adj[i].end();it++)
// {
// g.addEdge(*it,i);
// }
// }
// return g;
// }
bool isConnected()
{
//bool visited[V];
bool* visited=new bool[V];
for(int i=0;i<V;i++)
visited[i]=false;
int i=0;
int flag=0;
int n;
for(i=0;i<V;i++)
{
if(adj[i].size()>0)
{
n=i;
flag=1;
}
if(((int)adj[i].size()-in[i])==1 && in[i]==0) //selecting the start vertex i.e vertex with no incoming edges
{
n=i;
break;
}
}
if(i==V&&flag==0)
return 0;
DFSUtil(visited,n); //dfs to check if every node is reachable fro start vertex
for(int i=0;i<V;i++)
{
if(visited[i]==false && adj[i].size()>0)
return 0;
}
// Graph gr=reverseGraph();
// for(int i=0;i<V;i++)
// visited[i]=false;
// gr.DFSUtil(visited,n);
// for(int i=0;i<V;i++)
// {
// if(visited[i]==false && adj[i].size()>0)
// return 0;
// }
return 1;
}
bool isEuler()
{
int count=0;
int magnitude;
for(int i=0;i<V;i++) //check conditions on in and out edges, out edges=adj[].size
{
magnitude=in[i]-(int)adj[i].size();
if(magnitude<0)
magnitude=magnitude*-1;
if((magnitude)==1)
{
count=count+1;
}
else if(in[i]!=adj[i].size())
{
return 0;
}
}
if(count==1 || count>2)
return 0;
if(isConnected()==0) //check if graph is connected
return 0;
return 1;
}
};
int main()
{
int t;
//scanf("%d",&t);
cin>>t;
while(t--)
{
int n;
//scanf("%d",&n);
cin>>n;
string str;
if(n==1) //only one string entered
{
cin>>str;
cout<<"Ordering is possible.\n";
continue;
}
Graph g(26);
int src,des;
for(int i=0;i<n;i++)
{
cin>>str;
src=str[0]-'a';
des=str[str.length()-1]-'a';
g.addEdge(src,des);
}
if(g.isEuler())
{
cout<<"Ordering is possible.\n";
}
else
{
cout<<"The door cannot be opened.\n";
}
}
}
答案 0 :(得分:0)
在函数isConnected
中,您尝试通过在特定条件下中断for循环来找到没有传入边的起始顶点。如果未遇到此条件,则循环变量i
将包含值26,而不是0..25范围内的预期索引。当值26传递给DFSUtil
函数时,它将导致超出范围的数组访问。我在visited[v] = true;
导致这种情况发生的一个条件是链接网站上的重复单词的测试用例:
2
OK
确定
您查找起始顶点的检查不能很好地处理这种情况。