1. 程式人生 > >Gym - 101915D Largest Group 最大團

Gym - 101915D Largest Group 最大團

給你一個二分圖 問你最大團為多大

解一:狀壓DP

解二:二分圖最大匹配

二分圖的最大團=補圖的最大獨立集

二分圖最大獨立集=二分圖定點個數-最大匹配

//Hungary
#include<bits/stdc++.h>
using namespace std;
#define N 50
int useif[N];   //記錄y中節點是否使用 0表示沒有訪問過,1為訪問過
int link[N];   //記錄當前與y節點相連的x的節點
int mat[N][N]; //記錄連線x和y的邊,如果i和j之間有邊則為1,否則為0
int gn, gm;   //二分圖中x和y中點的數目
int can(int t) { int i; for (i = 1; i <= gm; i++) { if (useif[i] == 0 && mat[t][i]) { useif[i] = 1; if (link[i] == -1 || can(link[i])) { link[i] = t;
return 1; } } } return 0; } int MaxMatch() { int i, num; num = 0; memset(link, 0xff, sizeof(link)); for (i = 1; i <= gn; i++) { memset(useif, 0, sizeof(useif)); if (can(i)) { num
++; } } return num; } int main() { int TCASE; scanf("%d", &TCASE); while (TCASE--) { int n, k; int u, v; scanf("%d %d", &n, &k); gn = gm = n; memset(mat, 0, sizeof(mat)); for (int i = 1; i <= k; i++) { scanf("%d %d", &u, &v); mat[u][v] = 1; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { mat[i][j] = mat[i][j] ^ 1; } } int ans = n * 2; ans -= MaxMatch(); printf("%d\n", ans); } }
View Code