当前位置: 代码迷 >> 综合 >> 1009 - Back to Underworld(DFS)
  详细解决方案

1009 - Back to Underworld(DFS)

热度:14   发布时间:2023-12-12 14:21:10.0

题目连接

                        Time Limit: 4 second(s) Memory Limit: 32 MB

The Vampires and Lykans are fighting each other to death. The war has become so fierce that, none knows who will win. The humans want to know who will survive finally. But humans are afraid of going to the battlefield.

So, they made a plan. They collected the information from the newspapers of Vampires and Lykans. They found the information about all the dual fights. Dual fight means a fight between a Lykan and a Vampire. They know the name of the dual fighters, but don’t know which one of them is a Vampire or a Lykan.

So, the humans listed all the rivals. They want to find the maximum possible number of Vampires or Lykans.

Input
Input starts with an integer T (≤ 10), denoting the number of test cases.

Each case contains an integer n (1 ≤ n ≤ 105), denoting the number of dual fights. Each of the next n lines will contain two different integers u v (1 ≤ u, v ≤ 20000) denoting there was a fight between u and v. No rival will be reported more than once.

Output
For each case, print the case number and the maximum possible members of any race.

Sample Input
2
2
1 2
2 3
3
1 2
2 3
4 2

Output for Sample Input
Case 1: 2
Case 2: 3

Note
Dataset is huge, use faster I/O methods.

这道题题意就不多说了,我之前也是想了很多方法都但都是因为数据量太大都错了,就是没有想到二分染色标记这个巧妙的方法,相连的两个肯定是不同的颜色,对于同一个联通及来说,用这种方法就可以吧一个联通图的两个点集的大小求出来,然后对所有的联通图遍历一遍,吧最大电集的个数加起来就可以,至于如何遍历就直接用dfs就可以了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;const int N = 20020;
vector<int> vec[N];// 用vector容器存储与某个点相连的所有点
bool appear[N];
bool visited[N];
int sum, sum1;void dfs(int u, int flag)// 这里用了一个flag进行二分染色,染色为 0 和1 两种(妙)
{sum++;if(flag) sum1++;visited[u] = true;for(int i = 0; i < vec[u].size(); i++){int v = vec[u][i];if(!visited[v])dfs(v, !flag);}
}int main()
{int t, countt = 0;scanf("%d", &t);while(t--){int n;int max_index = 0;int ans = 0;scanf("%d", &n);for(int i = 0; i <= 20000; i++){appear[i] = visited[i] = false;vec[i].clear();//vec[i].reserve(N);//这个之所以写了一个初始化vector的容量,是因为为了减少时间,但是这道题所需的空间太大了// 会超内存限制的,想了解我说的这个减少时间的意思的话。可以去查一查vector的使用。 代码下面有连接。}while(n--){int u, v;scanf("%d%d", &u, &v);vec[u].push_back(v);vec[v].push_back(u);appear[u] = appear[v] = true;max_index = max(max_index, max(u, v));}for(int i = 1; i <= max_index; i++){if(!appear[i] || visited[i]) continue;sum = sum1 = 0; dfs(i, 0);ans += max(sum1, sum - sum1);}printf("Case %d: %d\n", ++countt, ans);}return 0;
}

vector的内存管理与效率

  相关解决方案