POJ 1308 Is It A Tree?

在此提供了兩種解法:(1)利用樹的性質,除了根節點入度爲0外,其餘節點入度均爲1;(2)利用並查集,但是並查集檢測是否存在多餘的邊後,還要檢測全部節點構成的是樹還是森林。比如測試數據 1 2 2 3 4 5 0 0。

Solution 1:

#include <iostream>
#include <vector>

using namespace std;

const int MAXSIZE = 10024;
vector<int> degree;
vector<bool> flags;

int main()
{
    int k = 0;
    int u, v;
    while( (cin >> u >> v) && (~u || ~v) )
    {
	degree.assign(MAXSIZE, 0);
	flags.assign(MAXSIZE, false);

	++k;
	degree[v]++;
	flags[u] = true;
	flags[v] = true;

	if( !u && !v )
	{
	    cout << "Case " << k << " is a tree." << endl;
	    continue;
	}

	while( (cin >> u >> v) && (u || v) )
	{
	    degree[v]++;
	    flags[u] = true;
	    flags[v] = true;
	}
	// Judge
	int cnt0 = 0, cnt1 = 0;
	int n = 0;
	int i;
	for(i = 0; i < MAXSIZE; ++i)
	{
	    if( flags[i] )
	    {
		++n;
		if( degree[i] == 1 )
		    ++cnt1;
		else if( degree[i] == 0 )
		    ++cnt0;
		else break;
	    }
	}
	if(i == MAXSIZE && cnt0 == 1 && cnt1 == n-1)
	    cout << "Case " << k << " is a tree." << endl;
	else cout << "Case " << k << " is not a tree." << endl;
    }
    return 0;
}

Solution 2:

#include <iostream>
#include <vector>

using namespace std;

const int MAXSIZE = 10024;
int k = 0;
vector<int> p, r;
vector<bool> vex;

void MakeSet()
{
    p.clear();
    p.resize( MAXSIZE );
    r.assign(MAXSIZE, 0);
    for(int i = 0; i < MAXSIZE; ++i)
	p[i] = i;
}

int FindSet(int c)
{
    if(p[c] != c)
	p[c] = FindSet(p[c]);
    return p[c];
}

void Union(int lc, int rc)
{
    int lp = FindSet(lc);
    int rp = FindSet(rc);
    if( r[lp] < r[rp] )
	p[lp] = rp;
    else 
    {
	p[rp] = lp;
	r[lp]==r[rp]?r[lp]++:NULL;
    }
}

int main()
{
    int u, v;
    while( (cin >> u >> v) && (~u || ~v) )
    {
	++k;
	if( !u && !v )
	{
	    cout << "Case " << k << " is a tree." << endl;
	    continue;
	}

	MakeSet();
	vex.assign(MAXSIZE, false);

	bool ans = true;
	do
	{
	    if( ans )
	    {
		vex[u] = true;
		vex[v] = true;

		if(FindSet(u) != FindSet(v))
		    Union(u, v);
		else
		    ans = false;
	    }
	}while( (cin >> u >> v) && (u || v) );

	if( ans )
	{
	    int s = -1;
	    for(int i = 0; i < MAXSIZE; ++i)
		if( vex[i] )
		{
		    if( s == -1 )
			s = FindSet( i );
		    else if( s != FindSet(i) )
		    {
			ans = false;
			break;
		    }
		}
	}

	cout << "Case " << k << (ans?" is a tree.":" is not a tree.") << endl;
    }
    return 0;
}


發佈了76 篇原創文章 · 獲贊 4 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章