1. 程式人生 > 其它 >21.10.28模擬 C

21.10.28模擬 C

給定一個圖,問這個圖能把所有點分成若干個集合,使得有邊相連的兩點所在集合編號是相鄰的

顯然,如果圖只有是二分圖才有解。圖的最長鏈(兩點之間最短路徑的最長長度)的長度+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;
}

本文來自部落格園,作者:{2519},轉載請註明原文連結:https://www.cnblogs.com/QQ2519/p/15479873.html