图可以划分为多个连通块,通过并查集来找到所有的连通块。对于每一个连通块,枚举块中所有的点作为根来跑bfs来找到最多的层数,把所有连通块最多的层数累加即为答案。因为有答案不存在的情况,因此在我们bfs的同时,赋给每个点一个层数h,再枚举它的出边,对于出边到达的点,没有访问过的直接赋给层数h+1;如果访问过了,则判断二者层数差值的绝对值是否为1。不为1则说明无解。
class Solution {
public:
int p[510];
int findd(int x){
return p[x]==x?x:p[x]=findd(p[x]);
}
void unionn(int x,int y){
x=findd(x),y=findd(y);
p[x]=y;
}
int magnificentSets(int n, vector<vector<int>>& edges) {
for(int i=1;i<=n;i++) p[i]=i;
vector<vector<int>> g(n+1);
vector<vector<int>> st(n+1);
for(auto t:edges){
unionn(t[0],t[1]);
g[t[0]].push_back(t[1]);
g[t[1]].push_back(t[0]);
}
for(int i=1;i<=n;i++){
int h=findd(i);
st[h].push_back(i);
}
int ans=0;
auto bfs=[&](int u){
vector<int> vis(n+1,0);
vector<int> d(n+1,0);
queue<int> q;
q.push(u);
vis[u]=1;
d[u]=1;
int k=0;
while(!q.empty()){
int sz=q.size();
while(sz--){
int x=q.front();
q.pop();
for(auto y:g[x]){
if(!vis[y]){
vis[y]=1;
d[y]=d[x]+1;
q.push(y);
}else if(abs(d[x]-d[y])!=1){
return -1;
}
}
}
k++;
}
return k;
};
for(int i=1;i<=n;i++){
int res=0;
for(auto u:st[i]){
int tmp=bfs(u);
if(tmp==-1) return -1;
res=max(res,tmp);
}
ans+=res;
}
return ans;
}
};