Tema
Da una gráfica acíclica dirigida con n puntos y m aristas. Deje que envíe algunos paracaidistas a aterrizar en ciertos puntos y caminar por todos los puntos. Los caminos de todos los paracaidistas no pueden superponerse. Es decir, busque la menor cobertura de bordes.
teorema
Cobertura de borde mínima = número de puntos-número máximo de coincidencia de gráfico bipartito
análisis
Debido a que las trayectorias de cada paracaidista no pueden superponerse, el grado máximo de entrada y salida de cada punto es 1. El
problema se simplifica para seleccionar algunos bordes de modo que el grado máximo de salida y el grado de entrada de todos los puntos sea 1.
Porque agregar un borde Puede salvar a un paracaidista, por lo que la respuesta = puntos-número de lados seleccionados
Debido a que el grado de salida y el grado de entrada solo pueden ser 1 o 0, pueden corresponder a coincidencias y no coincidencias en el gráfico bipartito.
Por lo tanto, separe el grado de salida y el grado de entrada de cada punto en dos conjuntos. Puede hacer coincidir gráficas bipartitas en dos conjuntos. El borde emparejado es el borde seleccionado en el gráfico.
Código AC
#include<iostream>
#include<cstring>
using namespace std;
const int maxn = 200;
const int inf = 1e9;
#define fast ios::sync_with_stdio(false); cin.tie(0);cout.tie(0);
int G[maxn][maxn];
int vis[maxn], match[maxn];
int n, m;
int find(int x){
for(int i = 1 ; i <= n ; i++){
if(G[x][i] && !vis[i]){
vis[i] = 1;
if(match[i] == 0 || find(match[i])){
match[i] = x;
return 1;
}
}
}
return 0;
}
int main(){
int T;
cin >> T;
while(T--){
cin >> n >> m;
memset(G, 0, sizeof G);
memset(match, 0, sizeof match);
int l, r;
for(int i = 1 ; i <= m ; i++){
cin >> l >> r;
G[l][r] = 1;
}
int ans = n;
for(int i = 1 ; i <= n ; i++){
for(int j = 1 ; j <= n ; j++)vis[j] = 0;
ans -= find(i);
}
cout << ans << endl;
}
}