本蒟蒻想到一种玄学做法:
首先第一步仍然是二分图染色判断可行性, 然后循环每个点作为起点BFS。
具体地说,将起点所属的集合记为1,然后与之相连的点放到集合2中...以此类推,每个点的值为其相邻已知点的值+1,然后找到所有方案(即将不同点作为起点)最大值。
虽然证明不出来,但是AC了...
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 205;
int n, col[N], t[N], ans;
bool vis[N];
vector<int> g[N];
string str;
queue<int> q;
void color(int x, bool c){
if(col[x] != -1){
if(col[x] != c) ans = -1;
return;
}
if(ans == -1) return;
col[x] = c;
for(int v : g[x]){
color(v, !c);
}
}
int BFS(int st){
for(int i = 1; i <= n; i++) t[i] = 0, vis[i] = 0;
q.push(st); t[st] = 1; vis[st] = 1;
while(!q.empty()){
int u = q.front(); q.pop();
for(int v : g[u])
if(!vis[v]){
vis[v] = 1;
t[v] = t[u] + 1;
q.push(v);
}
}
int maxn = 0;
for(int i = 1; i <= n; i++){
maxn = max(maxn, t[i]);
}
return maxn;
}
signed main(){
//二分图染色判断yes/no
//以每个点为起点,bfs找最大值
scanf("%d", &n);
for(int i = 1; i <= n; i++){
cin >> str; str = '$' + str;
for(int j = 1; j <= n; j++){
if(str[j] == '1') g[i].push_back(j);
}
}
for(int i = 1; i <= n; i++) col[i] = -1;
color(1, 0);
if(ans == -1){
printf("%d", -1);
return 0;
}
for(int i = 1; i <= n; i++){
ans = max(ans, BFS(i) );
}
printf("%d", ans);
return 0;
}