P6268 [SHOI2002]舞会
[SHOI2002]舞会
题目描述
某学校要召开一个舞会。已知学校所有 $n$ 名学生中,有些学生曾经互相跳过舞。当然跳过舞的学生一定是一个男生和一个女生。在这个舞会上,要求被邀请的学生中的任何一对男生和女生互相都不能跳过舞。求这个舞会最多能邀请多少个学生参加。
输入输出格式
输入格式
输入的第一行是 $n$ 和 $m$ 。其中 $n$ 是可选的学生的总数, $m$ 是已知跳过舞的学生的对数 ( $n \leq 1000$ , $m \leq 2000$ )。 然后有 $m$ 行,每行包括两个非负整数,表示这两个编号的学生曾经跳过舞。学生的编号从 $0$ 号到 $n - 1$ 号。
输出格式
输出文件仅一行,为一个数字,即能够邀请的最多的学生数。
输入输出样例
输入样例 #1
8 6
0 2
2 3
3 5
1 4
1 6
3 1
输出样例 #1
5
输入样例 #2
20 5
5 2
4 3
18 17
0 11
13 3
输出样例 #2
16
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 const int N = 3000; 7 int g[N][N]; 8 int match[N]; 9 int vis[N], now; 10 int n, m; 11 12 bool dfs(int x) 13 { 14 for(int i = 1; i <= n; i++) 15 { 16 if(g[x][i]) 17 { 18 if(vis[i] != now) 19 { 20 vis[i] = now; 21 if(!match[i] || dfs(match[i])) 22 { 23 match[i] = x; 24 return 1; 25 } 26 } 27 } 28 } 29 return 0; 30 } 31 32 int main() 33 { 34 scanf("%d %d",&n,&m); 35 for(int i = 1; i <= m; i++) 36 { 37 int a, b; 38 scanf("%d %d",&a,&b); 39 g[++a][++b] = 1; 40 g[b][a] = 1; 41 } 42 int res = 0; 43 44 for(int i = 1; i <= n; i++) 45 { 46 now++; 47 if(dfs(i)) res++; 48 } 49 printf("%d",n - res/2); 50 return 0; 51 }

浙公网安备 33010602011771号