我想知道我的图表是否是二分图,我有几个测试用例。如果我运行多个测试用例它不能正常工作,它总是会显示Bipartite。我很难搞清楚。对于一个案例,它适用于任何图形。
这是我的代码。
#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;
}
答案 0 :(得分:2)
您永远不会显式初始化marked
的内容,或者更确切地说,它指向的数组内容。
构造函数中的循环读取marked
的元素以决定如何分配给color
,但您从未初始化正在读取的marked
元素。
color
和edgeTo
的类似论据。
这意味着,虽然他们可能已经对第一种情况进行了预期的初始化,但很可能会使用在以后的情况下发生的任何值。
答案 1 :(得分:0)
同样Bipartite(Graph G)
正在调用Graph
的默认复制构造函数。可能不是你想要的。
请改为Bipartite(const Graph & G)
(也在dfs
中)。
如果没有new
,请不要delete
。
而是使用vector<vector<int>> adj;
,甚至为什么list
?并使用adj.resize(V);
在构造函数中重新启动它。
在您编辑相关代码后,当您使用new
分配数组时,您应该将其删除为数组,因此请使用delete[] color;
。
或完全停止使用new / delete。您可以再次使用std::vector<bool> color(G.V);
,避免new/delete
麻烦,并且默认情况下将所有值初始化为false
。
在现代C ++中,使用new
或delete
的原因很少(更像是“无”)(除非您编写一些低级库,或者您正在优化性能,并且你知道你在做什么。)