CF1105E Helping Hiasat

Maximum Independent Set

Immortal question, feel more than the difficulty of 2200

First to build map

It can be found no matter how many consecutive 1 operation, all operations can be seen as 1 1

This will then be used as a boundary of the block, the two successive operations into a group

Then each friend's name string into a digital hash map

At this point every friend will appear in which group have been processed out

Friends said the two are in conflict, if and only if the two friends also appear in any set

So between the two sides even friends, then map out on the building

 

When I think of the game here, then fucks with topological order, even water over the first 29 points

Later jzy chiefs, shouted maximum independent set, I suddenly realized

 

Then the answer is the largest independent set this picture

Original maximum independent set is the complement of the maximum group of FIG.

Because the range of 40 m, and direct violence timeout, so there must be optimized dp

MYY Gangster is a binary search ( Well, I do not want to write )

Of course, if advanced algorithms will also be directly over ( but I will not )

#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-- ) // Complements determined maximum group 
    { 
        S [ . 1 ] = I; 
        DFS ( . 1 , I + . 1 ); 
        DP [I] = ANS; 
    } 
    the printf ( " % D \ n- " , DP [ . 1 ]); 
}

 

Guess you like

Origin www.cnblogs.com/huangchenyan/p/11258414.html