https://atcoder.jp/contests/agc039/tasks/agc039_b
思路: 首先分析出不能满足题设条件的情况: 作一次bfs,若相邻结点的深度差不为1,则肯定不行,输出-1即可。
若满足题设条件,枚举每一个节点,对于每次枚举,都求出该情况下图的直径,输出所有情况中最大直径即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const ll N=1e5+5;
const ll mod=1e9+7;
int n;
char s[205][205];
int vis[205];
int dep[205];
struct node{
int a,b,d;
};
queue<node>q;
vector<int>v[205];
void clear(queue<node>& q){
queue<node> empty;
swap(empty,q);
}
int flag=1;
int main(){
std::ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++)
cin>>s[i];
for(int i=1;i<=n;i++){
for(int j=0;j<n;j++)
if(s[i][j]=='1')
v[i].push_back(j+1);
node t,g;
int ans=0;
int fff=1;
for(int k=1;k<=n;k++){
flag=1;
memset(vis,0,sizeof(vis));
for(int i=0;i<=n;i++) dep[i]=-1;
int pp=0;
t.a=0,t.b=k,t.d=1;
q.push(t);
while(!q.empty()){
t=q.front();
q.pop();
int b=t.b;
if(vis[b]) continue; //TLE
vis[b]=1;
dep[b]=t.d;
pp=b;
for(int i=0;i<v[b].size();i++){
if(vis[v[b][i]]==1){
if(abs(dep[v[b][i]]-dep[b])!=1)
flag=0;
continue;
}
else{
g.a=b,g.b=v[b][i];
g.d=t.d+1;
q.push(g);
}
}
}
memset(vis,0,sizeof(vis));
clear(q);
if(flag){
t.a=0,t.b=pp,t.d=1;
q.push(t);
while(!q.empty()){
t=q.front();
q.pop();
ans=max(ans,t.d);
int b=t.b;
if(vis[b]) continue; //TLE
vis[b]=1;
for(int i=0;i<v[b].size();i++){
if(vis[v[b][i]]==1){
continue;
}
else{
g.a=b,g.b=v[b][i];
g.d=t.d+1;
q.push(g);
}
}
}
}
if(flag==0) fff=0;
}
if(!fff) cout<<-1<<endl;
else cout<<ans<<endl;
return 0;
}