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 }
ezoj 1224 [RYOI2018R2]前前前任
posted @ 2018-09-02 15:14  KingSann  阅读(139)  评论(0编辑  收藏  举报