程序仅适用于一个测试用例 - 调试

时间:2016-09-09 16:22:27

标签: c++ debugging c++11 graph bipartite

我想知道我的图表是否是二分图,我有几个测试用例。如果我运行多个测试用例它不能正常工作,它总是会显示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;
}

2 个答案:

答案 0 :(得分:2)

您永远不会显式初始化marked的内容,或者更确切地说,它指向的数组内容。

构造函数中的循环读取marked的元素以决定如何分配给color,但您从未初始化正在读取的marked元素。

coloredgeTo的类似论据。

这意味着,虽然他们可能已经对第一种情况进行了预期的初始化,但很可能会使用在以后的情况下发生的任何值。

答案 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 ++中,使用newdelete的原因很少(更像是“无”)(除非您编写一些低级库,或者您正在优化性能,并且你知道你在做什么。)