Codeforces Round #533 (Div. 2)E. Helping Hiasat_求最大独立子集转换求最大团

题目链接:E. Helping Hiasat

题解:把夹在同一段1里面的人互相连边,然后问题就转换为求最大独立子集的大小,最大独立子集大小等于补图的最大团。最大图不会的可以看这篇博客,我也是看这个的

#include<bits/stdc++.h>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#define pb push_back
#define ll long long
#define PI 3.14159265
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define eps 1e-7
using namespace std;
const int N=50;
const int mod=1e9+7;
int n,m;
int g[N][N];
map<string ,int >mp;
vector<int>ve;
int ret=0;
int cnt[N],vis[N],ans;
bool dfs(int u,int d)
{
    for(int i=u+1;i<m;i++)
    {
        if(d+cnt[i]<=ans)return 0;
        if(g[u][i])
        {
            int j;
            for(j=0;j<d;j++)if(!g[i][vis[j]])break;
            if(j==d)
            {
                vis[d]=i;
                if(dfs(i,d+1))return 1;
            }
        }

    }
    if(d>ans)
    {
        ans=d;return 1;
    }
    return false;
}
int maxclique()
{
    ans=0;
    for(int i=m-1;i>=0;i--)
    {
        vis[0]=i;
        dfs(i,1);
        cnt[i]=ans;
    }
    return ans;
}
int main()
{
      std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
      cin>>n>>m;
      for(int i=0;i<=n;i++)
      {
            int op;
            if(i!=n)cin>>op;
            else op=1;
            if(op==1)
            {
                for(int j=0;j<ve.size();j++)
                {
                    for(int k=j+1;k<ve.size();k++)
                    {
                       g[ve[j]][ve[k]]=1,g[ve[k]][ve[j]]=1;
                       //cout<<"SSS"<<endl;
                    }
                }
                ve.clear();
            }
            else
            {
                string s;cin>>s;
                if(mp.count(s)==0)mp[s]=ret++;
                ve.pb(mp[s]);

            }
      }
      for(int i=0;i<m;i++)
      for(int j=0;j<m;j++)g[i][j]^=1;
      cout<<maxclique()<<endl;
}

猜你喜欢

转载自www.cnblogs.com/lhclqslove/p/10298902.html