http://codeforces.com/contest/1105/problem/E
E. Helping Hiasat
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Hiasat registered a new account in NeckoForces and when his friends found out about that, each one of them asked to use his name as Hiasat's handle.
Luckily for Hiasat, he can change his handle in some points in time. Also he knows the exact moments friends will visit his profile page. Formally, you are given a sequence of events of two types:
- 11 — Hiasat can change his handle.
- 22 ss — friend ss visits Hiasat's profile.
The friend ss will be happy, if each time he visits Hiasat's profile his handle would be ss.
Hiasat asks you to help him, find the maximum possible number of happy friends he can get.
Input
The first line contains two integers nn and mm (1≤n≤105,1≤m≤401≤n≤105,1≤m≤40) — the number of events and the number of friends.
Then nn lines follow, each denoting an event of one of two types:
- 11 — Hiasat can change his handle.
- 22 ss — friend ss (1≤|s|≤401≤|s|≤40) visits Hiasat's profile.
It's guaranteed, that each friend's name consists only of lowercase Latin letters.
It's guaranteed, that the first event is always of the first type and each friend will visit Hiasat's profile at least once.
Output
Print a single integer — the maximum number of happy friends.
Examples
input
Copy
5 3
1
2 motarack
2 mike
1
2 light
output
Copy
2
input
Copy
4 3
1
2 alice
2 bob
2 tanyaromanova
output
Copy
1
Note
In the first example, the best way is to change the handle to the "motarack" in the first event and to the "light" in the fourth event. This way, "motarack" and "light" will be happy, but "mike" will not.
In the second example, you can choose either "alice", "bob" or "tanyaromanova" and only that friend will be happy.
题目大意:有m个人,n组询问,每次询问若为1,则可以将当前账户名字更改,若为2,则再输入一个人的名字,第一次输入一定为1,问最多能让多少个人开心(及每次输入2后的那个人的名字和当前账户名字一样,那个人就是开心的)
解:可以将每个人名和一个数字对应,每两个1之间的人不可能同时开心(包括最后一个1后的人),那么在不可能同时开心的人之间连一条无向边,问题就转化成了求无向图中的最大点独立集的大小,而最大点独立集和补图中最大完全子图相同,就可以直接dfs将最大完全子图跑出来(图中只有40个点)
代码1:
#include <bits/stdc++.h>
using namespace std;
bool maps[45][45];
vector<int> best;
vector<int> now;
int ans;
int n;
void dfs(int pos){
if(pos==n+1){
if(now.size()>best.size()){
best=now;
ans=1;
} else if(now.size()==best.size()){
best=now;
ans++;
}
return;
}
bool flag=true;
for(int i=0;i<now.size();i++){
int nxt=now[i];
if(!maps[pos][nxt]){
flag=false;
break;
}
}
if(now.size()+(n-pos)>=best.size()){
if(flag){
now.push_back(pos);
dfs(pos+1);
now.pop_back();
}
dfs(pos+1);
}
}
int main() {
int m;
scanf("%d%d",&m,&n);
int cnt = 0,opt;
string s;
map<string,int> ma;
set<int> se;
set<int>::iterator it1,it2;
for(int i = 1;i <= n;++i)
for(int j = 1;j <= n;++j)
maps[i][j] = 1;
for(int i = 1;i <= m;++i)
{
scanf("%d",&opt);
if(opt == 1)
{
for(it1 = se.begin(); it1 != se.end();++it1)
for(it2 = se.begin(); it2 != se.end();++it2)
maps[*it1][*it2] = 0;
se.clear();
}
else
{
cin >> s;
if(ma.find(s) != ma.end())
se.insert(ma[s]);
else
{
ma[s] = ++cnt;
se.insert(cnt);
}
}
}
for(it1 = se.begin(); it1 != se.end();++it1)
for(it2 = se.begin(); it2 != se.end();++it2)
maps[*it1][*it2] = 0;
dfs(1);
cout<<best.size();
return 0;
}
代码2:
#include <bits/stdc++.h>
using namespace std;
int some[130][130];//±ðÓÃSTLÁË£¬ÕâÌâÀï¾ÍÄÜÊ¡Ò»°ë»¹¶àµÄʱ¼äÁË
int all[130][130];//ÕâÀïµÄÊý×éÈçÉÏËùÊö
int none[130][130];
int maps[130][130];//ÁÚ½Ó¾ØÕó£¬ÅжÏÓÐûÓбßÏàÁ¬ÊÇO(1)µÄ±È½Ï·½±ã
int degrees[130];//¼Ç¼¸÷¸ö½ÚµãµÄ¶ÈÊý
int ans;
bool cmp(int a,int b){
return degrees[a]>degrees[b];//¸ù¾Ý¶ÈÊýÅÅÐò£¬¶ÈÊý×î´óµÄ¿ÉÒÔ×÷Ϊpivotµã
}
void BronKerbosch(int pos,int al,int so,int no){
if(so==0 && no==0){
ans = max(ans,al);//ÕâÀïµÄall[pos]¼´ÎªÎÒÃǼ«´óÍÅ£¬ÒªÇó×î´óÍÅÖ»ÐèÒª±È½ÏÒ»ÏÂal´óС¼´¿É¡£
return;
}
int pivot;
if(so!=0){
pivot=some[pos][0];//ÅŹýÐòÁË£¬ËùÒÔµ±Ç°some¼¯ºÏµÄµÚÒ»¸öÔªËØÊǶÈÊý×î´óµÄµã
for(int i=0;i<al;i++)
all[pos+1][i]=all[pos][i];//´Ó±¾²ã³ö·¢µÄ±éÀúall¼¯ºÏµÄÇ°ÃæÔªËض¼ÊǺͱ¾²ãÒ»ÑùµÄ
}
for(int i=0; i<so; i++){
int nxt=some[pos][i];
if(maps[pivot][nxt])
continue;//pivotÓÅ»¯£¬pivotµÄÁڽӵ㲻¼ì²é
int nso=0,nno=0;//ÏÂÒ»²ãsome¼¯ºÏµÄ´óС£¬ÏÂÒ»²ãnone¼¯ºÏµÄ´óС
all[pos+1][al]=nxt;//°Ñµ±Ç°µ÷²éµã¼ÓÈëµ½ÏÂÒ»²ãµÄall¼¯ºÏÖÐ
for(int j=0; j<so; j++)
if(maps[nxt][some[pos][j]] && some[pos][j]!=-1)//ÇóºÍÁÚ½ÓµãµÄ½»¼¯
some[pos+1][nso++]=some[pos][j];
for(int j=0; j<no; j++)
if(maps[nxt][none[pos][j]])//ÇóºÍÁÚ½ÓµãµÄ½»¼¯
none[pos+1][nno++]=none[pos][j];
BronKerbosch(pos+1,al+1,nso,nno);
some[pos][i]=-1;none[pos][no++]=nxt;//´ÓsomeÖÐÒƳýÒѾµ÷²é¹ýµÄµã²¢ÒÆÈënone
}
}
int main(){
int n,m;
scanf("%d%d",&m,&n);
int cnt = 0,opt;
string s;
map<string,int> ma;
set<int> se;
set<int>::iterator it1,it2;
for(int i = 1;i <= n;++i)
for(int j = 1;j <= n;++j)
maps[i][j] = 1;
for(int i = 1;i <= m;++i)
{
scanf("%d",&opt);
if(opt == 1)
{
for(it1 = se.begin(); it1 != se.end();++it1)
{
degrees[*it1] += se.size();
for(it2 = se.begin(); it2 != se.end();++it2)
maps[*it1][*it2] = 0;
}
se.clear();
}
else
{
cin >> s;
if(ma.find(s) != ma.end())
se.insert(ma[s]);
else
{
ma[s] = ++cnt;
se.insert(cnt);
}
}
}
for(it1 = se.begin(); it1 != se.end();++it1)
{
degrees[*it1] += se.size();
for(it2 = se.begin(); it2 != se.end();++it2)
maps[*it1][*it2] = 0;
}
int so=0;
for(int i=1;i<=n;i++)
some[0][so++]=i;//Ò»¿ªÊ¼some¼¯ºÏÒª°üº¬ËùÓнڵã
sort(some[0]+1,some[0]+n+1,cmp);
ans=0;
BronKerbosch(0,0,so,0);//Ò»¿ªÊ¼²ãÊýΪ0£¬allºÍnone¶¼Îª¿Õ
printf("%d",ans);
return 0;
}