問題の説明
このアカウントは持っている、上記のソーシャルネットワーキングサイトで新しいアカウントにサインアップ((nは\ nは10当量\ ^ 5)\) を記録回。さもないと、あなたはID一度変更、またはのためのIDであるされている(\ | | S(S \ \)40当量) の友人があなたのスペースを訪問しました。
あなたが持っています\(40当量(M \ )\) の友人を。それぞれの友人は、少なくとも一度あなたのスペースを訪問します。これはあなたの最初の訪問の友人のすべてのスペース、あなたのIDであり、それは同じIDだ場合、彼は幸せになります。あなたが最も幸せを作ることができますどのように多くの人々下さい。
入力形式
最初の2つの正の整数の行のn、mが次のn行たび記録、次の2つの形式を表します。
1
2秒
もし一度1つの手段は、IDを変更する場合は、2はあなたのスペースに一度あなたの友人の訪問のためのIDを表します。
最初のレコードは1でなければならないことを確実にするために。
出力フォーマット
ライン、最も幸せを作ることができますどのように多くの友人を示す正の整数。
サンプル入力
5 3
1
2 motarack
2マイク
1つの
2光
サンプル出力
2
解決
一人一人の時間が設定時間に記録されて表示されている場合は、すべての人の登場となっています。セットの交差点の二人が空集合である場合と、その後、二人は同時に幸せになることができます。このように、問題は、これらの人々を最大限に活用しようとしている人々に変換され、時間の積集合が空で表示されます。交差点は、それが問題のダイヤグラム最大の独立セットになり、でも二人側の空ではありません。
判決の交差点に関して具体的に、我々は、ビットセットとそれぞれの人のための2進数を維持する人の場合は2つの2進数と0ではないことができ、それは共通の基盤があることを意味します。
コード
#include <iostream>
#include <cstdio>
#include <map>
#include <cstring>
#include <bitset>
#include <algorithm>
#define N 100002
#define M 42
using namespace std;
int head[M],ver[M*M],nxt[M*M],l;
int n,m,i,j,cnt1,cnt2,ans,p[M];
bool vis[M];
map<string,int> d;
bitset<N> b[M];
void insert(int x,int y)
{
l++;
ver[l]=y;
nxt[l]=head[x];
head[x]=l;
}
int main()
{
cin>>n>>m;
for(i=1;i<=m;i++) p[i]=i;
for(i=1;i<=n;i++){
int op;
string s;
cin>>op;
if(op==1) cnt1++;
else{
cin>>s;
if(d[s]==0) d[s]=++cnt2;
b[d[s]][cnt1]=1;
}
}
for(i=1;i<=m;i++){
for(j=i+1;j<=m;j++){
if((b[i]&b[j]).any()) insert(i,j),insert(j,i);
}
}
int t=100;
while(t--){
random_shuffle(p+1,p+m+1);
int tmp=0;
memset(vis,0,sizeof(vis));
for(i=1;i<=m;i++){
if(!vis[p[i]]){
tmp++;
for(j=head[p[i]];j;j=nxt[j]) vis[ver[j]]=1;
}
}
ans=max(ans,tmp);
}
printf("%d\n",ans);
return 0;
}