给定一个图,问这个图能把所有点分成若干个集合,使得有边相连的两点所在集合编号是相邻的
显然,如果图只有是二分图才有解。图的最长链(两点之间最短路径的最长长度)的长度+1就是最多集合数
对于直径中衍生的边,可以直接划分到直径中的集合,由于直径的特性,该满足衍生边的所集合数量一定不会超过直径中能够提供的集合数量。
int vis[N], d[N], st, ans;
std::queue<int>q;
int color[N];
int rr,tt;
inline void bfs(int sx) {
q.push(sx);
d[sx] = 0;
vis[sx] = st;
while(q.size()) {
int y(q.front());
q.pop();
rep(i, 1, n) {
if(!a[i][y] || vis[i] == st) continue;
vis[i] = st;
d[i] = d[y] + 1;
q.push(i);
if(d[i]>ans){
rr=sx;tt=i;
ans=d[i];
}
}
}
}
int main() {
freopen("c.in", "r", stdin);
freopen("c.out", "w", stdout);
cin >> n;
char ch;
rep(i, 1, n) {
rep(j, 1, n) {
cin >> ch;
if(ch == '1') {
a[i][j] = a[j][i] = 1;
}
}
}
memset(color, 0xff, sizeof color);
int q[N];
rep(i, 1, n) {
if(!~color[i]) {
q[q[0] = 1] = i;
color[i] = 0;
rep(kkk, 1, q[0]) {
int x = q[kkk];
rep(y,1,n) {
if(!a[x][y]) continue;
if(~color[y] && color[y] != (color[x] ^ 1)) {
puts("-1");
return 0;
}
if(!~color[y]) {
q[++q[0]] = y;
color[y] = color[x] ^ 1;
}
}
}
}
}
rep(i, 1, n) {
st = i;
bfs(i);
}
cout<<ans + 1 << '\n';
return 0;
}