ezoj 1224 [RYOI2018R2]前前前任
给定$n$个节点,以及$m$条关系,每个关系可以覆盖两个不同的节点
要求用最少的关系来覆盖所有的节点
保证每个节点都会被一条关系覆盖
$n \le 500,m \le 1000$
按照关系对节点连边,那么就是要求找出尽可能多的边,使得不存在同时处于两条边上的点(其余的点就必须用一条边来覆盖了)
换而言之,求出这张图的最大匹配个数$x$,那么答案就是$n-x$
由于数据比较水,可以假装它是个二分图直接在上面跑最大匹配
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 510; 4 vector<int> g[N]; 5 int mat[N], vis[N], n, m, T; 6 7 inline void read(int &x) { 8 char c = x = 0; 9 while(!isdigit(c)) c = getchar(); 10 while(isdigit(c)) x = x * 10 + c - '0', c = getchar(); 11 } 12 13 int dfs(int u) { 14 vis[u] = T; 15 for(int i = 0 ; i < g[u].size() ; ++ i) { 16 int v = g[u][i]; 17 if(vis[v] == T) continue; 18 vis[v] = T; 19 if(!mat[v] || dfs(mat[v])) { 20 mat[v] = u, mat[u] = v; 21 return 1; 22 } 23 } 24 return 0; 25 } 26 27 int main() { 28 read(n), read(m); 29 for(int i = 1, u, v ; i <= m ; ++ i) 30 read(u), read(v), g[u].push_back(v), g[v].push_back(u); 31 int res = 0; 32 for(int i = 1 ; i <= n ; ++ i) 33 if(!mat[i]) 34 ++ T, res += dfs(i); 35 printf("%d", n - res); 36 }