LOJ 1373 最大团
题意: 给出了n个阳离子和m个阴离子,给出了他们之间的吸引关系。 现在想要求出一个集合,这个集合中至少有一个阳离子, 也至少有一个阴离子。 要求每个阳离子吸引所有的阴离子。求出这个集合中元素的最大数目是多少?
思路: 这道题开始想的时候没有思路,后来知道是一个最大团, 最大团等于节点数减去最大匹配。
但是普通的最大团左右集合可以为空。 但是这里要求必须至少有一个元素, 这里我们可以枚举至少的那个点对,然后再求最大团。
AC代码:
View Code
1 #include <cstdio> 2 #include <cstring> 3 #include <string> 4 #include <iostream> 5 #include <queue> 6 #include <vector> 7 using namespace std; 8 const int N = 505; 9 10 struct EDGE 11 { 12 int u, v, next; 13 } edge[N*N]; 14 15 int num, head[N], cx[N], cy[N], n, m; 16 bool used[N]; 17 char map[N][N]; 18 19 void init() 20 { 21 scanf("%d%d", &n, &m); 22 for(int i=1; i<=n; i++) 23 scanf("%s", map[i]+1); 24 } 25 26 void add(int u, int v) 27 { 28 edge[num].u = u; 29 edge[num].v = v; 30 edge[num].next = head[u]; 31 head[u] = num++; 32 } 33 34 bool can(int u) 35 { 36 int v; 37 for(int i=head[u]; i!=-1; i=edge[i].next) 38 { 39 v = edge[i].v; 40 if(used[v]) continue; 41 used[v] = 1; 42 if(cy[v] == -1 || can(cy[v]) ) 43 { 44 cx[u] = v; 45 cy[v] = u; 46 return true; 47 } 48 } 49 return false; 50 } 51 52 int xiyali(int total) 53 { 54 int ans = 0; 55 memset(cx, -1, sizeof(cx)); 56 memset(cy, -1, sizeof(cy)); 57 for(int i=1; i<=n; i++) 58 { 59 memset(used, 0, sizeof(used)); 60 if(cx[i] == -1 && can(i)) 61 ans++; 62 } 63 return total-ans; 64 } 65 66 void solve() 67 { 68 int ans = 0, u, v; 69 vector<int> g1, g2; 70 for(int i=1; i<=n; i++) 71 { 72 73 for(int j=1; j<=m; j++) 74 { 75 76 if(map[i][j] == '1') 77 { 78 g1.clear(); 79 g2.clear(); 80 for(int k=1; k<=n; k++) 81 { 82 if(map[k][j] == '1' && k!=i) 83 g1.push_back(k); 84 } 85 for(int k=1; k<=m; k++) 86 { 87 if(map[i][k] == '1' && k!=j) 88 g2.push_back(k); 89 } 90 num = 0; 91 memset(head, -1, sizeof(head)); 92 for(int k1=0; k1 <g1.size(); k1++) 93 { 94 u = g1[k1]; 95 for(int k2=0; k2<g2.size(); k2++) 96 { 97 v = g2[k2]; 98 if(map[u][v] == '0') 99 add(u, v); 100 } 101 } 102 ans = max(ans, 2+xiyali(g1.size()+g2.size())); 103 104 } 105 } 106 } 107 printf("%d\n", ans); 108 } 109 110 int main() 111 { 112 int t; 113 scanf("%d", &t); 114 for(int i=1; i<=t; i++) 115 { 116 init(); 117 printf("Case %d: ",i); 118 solve(); 119 } 120 return 0; 121 }


浙公网安备 33010602011771号