CF1105E Helping Hiasat
Posted huangchenyan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1105E Helping Hiasat相关的知识,希望对你有一定的参考价值。
最大独立集
神仙题,感觉不止2200的难度
先要建图
可以发现无论有多少个连续的1操作,都是可以看做1次1操作
那么可以将以这1作为分组的界限,将连续的2操作分为一组
然后将每一个朋友姓名的字符串用map哈希成数字
此时将每一个朋友在哪一组出现过都处理出来
称两个朋友是冲突的,当且仅当这两个朋友同时出现在任意一组中
那么将这两个朋友之间连边,那么图就建出来了
比赛时我就想到这里,然后用拓扑序乱搞,竟然水过了前29个点
后来jzy大佬,喊了一声最大独立集,我就恍然大悟
然后答案就是这张图的最大独立集
最大独立集就是原图补图的最大团
因为m是40的范围,直接暴力会超时,所以要有dp优化
MYY大佬是折半搜索的(好吧我不想写)
当然,如果会高级算法也能直接过(然而我不会)
#include <bits/stdc++.h> #pragma GCC optimize(2) #define ll long long using namespace std; const int MAXN=100000+10; int n,m,w,si[51],vi[51],ans,g; int MIN,fx[51][51],dp[51],s[51]; map <string,int> mp; struct node int op; string name; sh[MAXN]; vector <int> f[MAXN],ti[51],e[51]; set <pair<int,int> > q; bool check(int x,int y) for (int i=0;i<(int)ti[x].size();i++) vector <int> :: iterator it; it=lower_bound(ti[y].begin(),ti[y].end(),ti[x][i]); if (it==ti[y].end()) continue; if (*it==ti[x][i]) return true; return false; bool judge(int x,int end) for (int i=1;i<end;i++) if (!fx[s[i]][x]) return false; return true; void dfs(int x,int wh)//暴力求出补图的最大团 if (x+m-wh+1<=ans || x+dp[wh]<=ans) return; for (int i=wh;i<=m;i++) if (judge(i,x+1)) s[x+1]=i; dfs(x+1,i+1); if (x>ans) ans=x; int main() scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&sh[i].op); if (sh[i].op==2) cin>>sh[i].name; if (mp[sh[i].name]==0) w++; mp[sh[i].name]=w;//离散化 int bl=-1; w=0; for (int i=1;i<=n;i++)//分组 if (bl==-1 && sh[i].op==2) w++; bl=0; f[w].push_back(mp[sh[i].name]); else if (bl==0 && sh[i].op==2) f[w].push_back(mp[sh[i].name]); else if (bl==0 && sh[i].op==1) bl=-1; for (int i=1;i<=w;i++) for (int j=0;j<(int)f[i].size();j++) ti[f[i][j]].push_back(i); for (int i=1;i<=m;i++) for (int j=i+1;j<=m;j++) if (check(i,j)) e[i].push_back(j); e[j].push_back(i); for (int i=1;i<=m;i++) for (int j=1;j<=m;j++) fx[i][j]=1; for (int i=1;i<=m;i++) for (int j=0;j<(int)e[i].size();j++) fx[i][e[i][j]]=0;//建出原图的补图 fx[i][i]=0; dp[m]=1; ans=0; for (int i=m-1;i>=1;i--)//求出补图的最大团 s[1]=i; dfs(1,i+1); dp[i]=ans; printf("%d\n",dp[1]);
以上是关于CF1105E Helping Hiasat的主要内容,如果未能解决你的问题,请参考以下文章