我正在尝试解决SPOJ问题is it a tree ?,我必须检查图表是否为树? 在这个问题中,我使用DFS来检测图表是否有循环..
我的代码是..
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <string.h>
using namespace std;
typedef long long int64;
typedef unsigned long long uint64;
#define two(X) (1<<(X))
#define twoL(X) (((int64)(1))<<(X))
#define contain(S,X) (((S)&two(X))!=0)
#define containL(S,X) (((S)&twoL(X))!=0)
const double pi=acos(-1.0);
const double eps=1e-11;
template<class T> inline void checkmin(T &a,T b){if(b<a) a=b;}
template<class T> inline void checkmax(T &a,T b){if(b>a) a=b;}
template<class T> inline T sqr(T x){return x*x;}
typedef pair<int,int> ipair;
#define SIZE(A) ((int)A.size())
#define LENGTH(A) ((int)A.length())
#define MP(A,B) make_pair(A,B)
#define PB(X) push_back(X)
int scanInt()
{
char c;
int ans=0;
while(true)
{
c=getchar_unlocked();
if(c==' ' || c=='\n')
return ans;
ans=(ans<<3)+(ans<<1)+c-'0';
}
}
bool applyDFS(vector<vector<int> > &graph,int n)
{
queue <int> st;
int i,j=0;
vector<bool> visited(n+1,false);
int node=1;
st.push(1);
while(!st.empty())
{
node=st.front();
st.pop();
if(visited[node])
{
return false;
}
visited[node]=true;
for(i=0;i<graph[node].size();i++)
{
if(!visited[graph[node][i]])
st.push(graph[node][i]);
}
j++;
}
return j==n?true:false;
}
int main()
{
int n,m,x,y,i;
//freopen("input.txt","r",stdin);
n=scanInt();
m=scanInt();
vector <vector<int> > graph(n+1);
stack <int > st;
for(i=0;i<m;i++)
{
x=scanInt();
y=scanInt();
graph[x].PB(y);
graph[y].PB(x);
st.push(x);
}
if(applyDFS(graph,n))
cout<<"YES\n";
else
cout<<"NO\n";
return 0;
}
当我提交解决方案时,我收到了“超出时间限制”的消息。有没有更好的方法来解决这个问题?
答案 0 :(得分:4)
正如kevmo314在他的评论中所提到的,我们需要检查图表的连接性,边缘的数量正好是n-1,以确保图形是树。
所以有两个观察结果:
如果边数为n - 1
,我们只需要检查连接性。
使用disjoint set解决此问题,因为每个边缘(如果是树),此边缘应连接两个断开连接的组件,否则,此图形不是树。因此,时间复杂度为O(n),因为只有n - 1
边缘需要检查。