C++ 该程序只在一个测试用例(调试)下运行良好
我想知道我的图是否是二部图,我有几个测试用例。如果我运行多个测试用例,它不能正常工作,它总是显示二分体。我很难弄明白。仅在一种情况下,它适用于任何图形。C++ 该程序只在一个测试用例(调试)下运行良好,c++,debugging,c++11,graph,bipartite,C++,Debugging,C++11,Graph,Bipartite,我想知道我的图是否是二部图,我有几个测试用例。如果我运行多个测试用例,它不能正常工作,它总是显示二分体。我很难弄明白。仅在一种情况下,它适用于任何图形。 这是我的代码。 #include <iostream> #include <cstdio> #include <stack> #include <list> using namespace std; class Graph { public: int V;
这是我的代码。
#include <iostream>
#include <cstdio>
#include <stack>
#include <list>
using namespace std;
class Graph
{
public:
int V;
list<int> *adj;
Graph(int V);
void addEdge(int v, int w);
};
Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
}
void Graph::addEdge(int v, int w)
{
adj[v].push_back(w);
adj[w].push_back(v);
}
class Bipartite
{
private:
bool isBipartite;
bool *color;
bool *marked;
int *edgeTo;
stack<int> cycle;
public:
Bipartite(Graph G)
{
isBipartite = true;
color = new bool [G.V];
marked = new bool [G.V];
edgeTo = new int [G.V];
for (int v = 0; v < G.V; v++)
{
if (!marked[v])
{
color[v] = false;
dfs(G, v);
}
}
delete color;
delete marked;
delete edgeTo;
}
void dfs(Graph G, int v)
{
marked[v] = true;
list<int>::iterator w;
for (w = G.adj[v].begin(); w != G.adj[v].end(); w++)
{
if (!cycle.empty())
return;
if (!marked[*w])
{
edgeTo[*w] = v;
color[*w] = !color[v];
dfs(G, *w);
}
else if (color[*w] == color[v])
{
isBipartite = false;
cycle.push(*w);
for (int x = v; x != *w; x = edgeTo[x])
{
cycle.push(x);
}
cycle.push(*w);
}
}
}
bool isBi()
{
return isBipartite;
}
};
void solve(int n,int **p){
long long int x,y;
Graph g(n);
for(x=0;x<n;x++)
for(y=0;y<n;y++)
{
if(p[x][y]==1)
g.addEdge(x,y);
}
Bipartite b(g);
if (b.isBi())
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
int main()
{
long long int i,j,t,x,m,y,a,b;
int **p,n;
cin>>t;
for(i=0;i<t;i++)
{
cin>>n>>m;
p=new int*[n]();
for(x=0;x<n;x++)
{
p[x]=new int[n]();
}
for(j=0;j<m;j++)
{
cin>>a>>b;
a=a-1;
b=b-1;
p[a][b]=1;
p[b][a]=1;
}
for(x=0;x<n;x++)
{
for(y=0;y<n;y++)
{
if(x!=y)
{
p[x][y]=1-p[x][y];
}
}
}
/* for(x=0;x<n;x++)
{
for(y=0;y<n;y++)
cout<<p[x][y]<<" ";
cout<<"\n";
}
*/
solve(n,p);
}
return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
类图
{
公众:
INTV;
列表*adj;
图形(INTV);
无效补遗(整数v,整数w);
};
图形::图形(intv)
{
这个->V=V;
adj=新列表[V];
}
void图::addEdge(int v,int w)
{
形容词[v]。推回(w);
形容词[w]。推回(v);
}
类二部
{
私人:
布尔是二部的;
颜色;
布尔*标记;
int*edgeTo;
堆栈周期;
公众:
二部图(图G)
{
isBipartite=true;
颜色=新布尔值[G.V];
标记=新布尔值[G.V];
edgeTo=新整数[G.V];
对于(int v=0;v 对于(x=0;x,您从未显式初始化标记为
的的内容,或者更准确地说,初始化它所指向的数组的内容
构造函数中的循环读取标记为
的元素,以决定如何分配给颜色
,但从未初始化正在读取的标记为
的元素
color
和edgeTo
的类似参数
这意味着,虽然他们可能已经对第一种情况进行了预期的初始化,但很可能正在使用后来出现的任何值。还有Bipartite(Graph G)
正在调用Graph
的默认副本构造函数。可能不是您想要的
尝试使用Bipartite(const-Graph&G)
(也在dfs
中)
如果没有delete
,不要执行new
与其使用向量adj;
,为什么还要使用列表
?还不如在构造函数中使用adj.resize(V);
编辑相关代码后,当您使用
new
分配数组时,您也应该将其作为数组删除,因此使用delete[]color;
或者完全停止使用new/delete。同样,您可以使用std::vector color(G.V);
,避免了new/delete
的麻烦,并且默认情况下将所有值初始化为false
<>在现代C++中,很少有(更像“没有”)的理由使用<代码>新< /COD>或<代码>删除<代码>(除非你编写了一些低级库,或者你正在优化性能,你知道你在做什么).显式初始化变量。为它们赋值。现在代码运行正常,但我的实际问题是:它没有通过所有测试用例。我的实际问题是:我想实际检查是否可以将我的图划分为两个团(完整的子图).我所做的是补充邻接矩阵并检查二部。但它不起作用,你知道为什么吗?如果它没有通过所有测试用例,那么它就不“起作用”。我上面提到的问题得到了解决,但实际问题是检查:“我是否可以将我的图分成两个团(完整子图).我的方法:我所做的是补充邻接矩阵并检查二分体“现在代码工作正常,但我的实际问题是:它没有通过所有测试用例。我的实际问题是:我想实际检查是否可以将我的图划分为两个团(完整子图)。我所做的是补充邻接矩阵并检查二分体。但它不起作用,知道为什么吗?@Born2Code我不确定我是否得到任务描述。所以,如果你有两个人,相互联系,那么答案是“是”?(每个人组成自己的城市=集团,他们之间的联系被忽略)那么你的邻接补码将是空边集?我没有检查你的来源,它会回答为“bipartition=OK”吗?无论如何,我对图论有点生疏,无法判断你的想法是否正确,但看不出明显的问题(除了双分区必须处理分离的子图).但我懒得检查你的代码。检查这个:在第一种情况下,我可以把它们分成两个城市,一个在一个城市,两个和三个在另一个城市。[因为两个和三个互相认识]在第二种情况下,我不能把它们分开,因为它们在上述条件下无法分开。[好像我分开了,它们都不会互相认识]在第三种情况下,我可以分为两组,一组是1,2,3,另一组是4,5,6。因为他们彼此都认识。@Born2Code乍一看看起来还行。继续查找失败的测试用例和调试(同时验证单个公民输入、无公民输入、完整图形输入等)。但是您发布的代码看起来很容易有mem