Codeforces Round #533 (Div. 2) E. Helping Hiasat(最大独立集)

题目链接:https://codeforces.com/contest/1105/problem/E

题意:有 n 个事件,op = 1 表示我可以修改昵称,op = 2 表示一个名为 s_i 的朋友查询我当前的名字。一个朋友是高兴的当且仅当他每次查询我的名字都为 s_i,保证每个朋友至少查询一次我的名字,问最多可以有多少个朋友高兴。

题解:在我两次修改昵称之间,若出现不同的朋友,则他们是互斥的,可以在他们之间连一条边,然后求图的最大独立集,而原图的最大独立集等于补图的最大团,所以求补图的最大团即可。(模板)

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define ull unsigned long long
 5 #define mst(a,b) memset((a),(b),sizeof(a))
 6 #define mp(a,b) make_pair(a,b)
 7 #define pi acos(-1)
 8 #define pii pair<int,int>
 9 #define pb push_back
10 #define lowbit(x) ((x)&(-x))
11 const int INF = 0x3f3f3f3f;
12 const double eps = 1e-6;
13 const int maxn = 1e5 + 10;
14 const int maxm = 1e6 + 10;
15 const ll mod =  1e9 + 7;
16 
17 int n,m,tot = 0;
18 map<string,int>ma,have;
19 int op[maxn],a[50][50];
20 string s[maxn];
21 int ans,cnt[50],group[50],vis[50];
22 
23 bool dfs(int u,int pos) {
24     for(int i = u + 1; i <= n; i++) {
25         if(cnt[i] + pos <= ans) return false;
26         if(a[u][i]) {
27             int j;
28             for(j = 0; j < pos; j++)
29                 if(!a[i][vis[j]]) break;
30             if(j == pos) {
31                 vis[pos] = i;
32                 if(dfs(i,pos + 1)) return true;
33             }
34 
35         }
36     }
37     if(pos > ans) {
38         for(int i = 0; i < pos; i++) group[i] = vis[i];
39         ans = pos;
40         return true;
41     }
42     return false;
43 }
44 
45 void maxclique() { //最大团
46     ans = -1;
47     for(int i = n; i > 0; i--) {
48         vis[0] = i;
49         dfs(i,1);
50         cnt[i] = ans;
51     }
52 }
53 
54 
55 int main() {
56 #ifdef local
57     freopen("data.txt", "r", stdin);
58 //    freopen("data.txt", "w", stdout);
59 #endif
60     scanf("%d%d",&m,&n);
61     for(int i = 1; i <= m; i++) {
62         scanf("%d",&op[i]);
63         if(op[i] == 2) {
64             cin >> s[i];
65             if(ma.find(s[i]) == ma.end()) ma[s[i]] = ++tot;
66         }
67     }
68     vector<int>vec;
69     for(int i = 1; i <= m; i++) {
70         if(op[i] == 1) {
71             have.clear();
72             for(int i = 0; i < vec.size(); i++) {
73                 for(int j = i + 1; j < vec.size(); j++) {
74                     a[vec[i]][vec[j]] = a[vec[j]][vec[i]] = 1;
75                 }
76             }
77             vec.clear();
78         } else if(have.find(s[i]) == have.end()) vec.pb(ma[s[i]]);
79     }
80     for(int i = 0; i < vec.size(); i++) {
81         for(int j = i + 1; j < vec.size(); j++) {
82             a[vec[i]][vec[j]] = a[vec[j]][vec[i]] = 1;
83         }
84     }
85     for(int i = 1; i <= n; i++)
86         for(int j = 1; j <= n; j++) a[i][j] ^= 1;
87     maxclique();
88     if(ans < 0) ans = 0;
89     printf("%d\n",ans);
90     return 0;
91 }

猜你喜欢

转载自www.cnblogs.com/scaulok/p/10296835.html