知识点:广度优先搜索
这个题应该是顶级里面最简单的一道题,用到的知识只有广搜,看题目是时间是1秒,数据的规模是10的三次方,发现用n方的复杂度就可以过,然后发现题目要求联通块的个数,两种搜索都可以,但是第二个问题求的是图里面的最长最短路,无权图最短路用广搜再适合不过,所以就这么写了,
每次广搜找出这个点在它联通的图里面最长的最短路,更新答案即可,一句话概括就是暴力广搜,然后同时记录第一个答案,需要注意一点的是,题目的边数一定要开到合适的大小,不然就会段错误,也就是无向完全图和有向完全图的边数是多少,
- #include
-
- using namespace std;
-
- const int N = 1005;
-
- int tot, ver[N * N], nxt[N * N], head[N], ans, vis[N];
-
- void add(int x, int y) {
- ver[++tot] = y;
- nxt[tot] = head[x]; head[x] = tot;
- }
-
- void bfs(int x) {
- int dist[N];
- memset(dist, -1, sizeof(dist));
- dist[x] = 0;
- queue<int> q;
- q.push(x);
- while (!q.empty()) {
- int now = q.front(); q.pop();
- vis[now] = 1;
- ans = max(ans, dist[now] - 1);
- for (int i = head[now]; i; i = nxt[i]) {
- int y = ver[i];
- if (dist[y] != -1) continue;
- q.push(y);
- dist[y] = dist[now] + 1;
- }
- }
- }
-
- int main() {
- int n;
- cin >> n;
- for (int i = 1; i <= n; i++) {
- int k;
- cin >> k;
- for (int j = 0; j < k; j++) {
- int x;
- cin >> x;
- int ok = 1;
- for (int u = head[i]; u; u = nxt[u]) {
- int y = ver[u];
- if (y == x) ok = 0;
- }
- if (!ok) continue;
- add(i, x); add(x, i);
- }
- }
- int cnt = 0;
- for (int i = 1; i <= n; i++) {
- if (!vis[i]) cnt++;
- bfs(i);
- }
- cout << cnt << " " << ans;
- return 0;
- }