主要代码及思想来自http://zhyu.me/acm/zoj-3526.html

略有改动

 

这题卡了很久,然后想到网络流,键一个超级源点,连所有人,流量为2,然后每个人连能与其邻座的人,流量为1

在把每个人连超级汇点,流量为2,如果最大流等于人数两倍,就表示有解。

源点连每个人2流量,表示一个人两边都要坐人。人数为1或2的时候特判一下,可惜,超时。

不过,像下文一样缩点,应该可以吧。。。

 

/*
题意:n个人参加party,每个人的兴趣都是ACG (Anime, Comic and Game)
中的一种或几种,现在要让所有人坐成一圈,并且要让相邻的人至少有一种
共同兴趣,现在给出每个人的兴趣,问这样的安排方法是否可行。

思路:看完题就想把每个人看作一个点,有相同兴趣的人之间连边,然后…
然后这不是Hamilton回路嘛?!NP啊!n有64,不是很大,于是决定爆搞,
先用Dirac 定理(判断Hamilton回路的充分性 不是必要性)判一下,不行
再搜,然后还是TLE……想到缩点可是没想明白怎么缩,就一直悲剧到比赛结束……

缩点方法:对于AAAAAAA这种,缩成一个点就好,一个点可以和周围连起来就
全都能连起来;对于ACACACACA这种,要缩成两个点,因为要是剩下的只有一
个A和一个C,缩成一个点是不行的,但是实际上是可行的;对于ACGACGACG这
种当然就是缩成三个点了。然后图中最多只有1+1+1+2+2+2+3=12个点,直接
DFS判断即可
*/

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct Edge 
{
int v, next;
}edge[50];
char s[7][4]={"A", "C", "G", "AC", "AG", "CG", "ACG"};
int n, ne;
int head[8];
int cnt[8], f[50];
char name[15], like[15];

void addedge(int from, int to)
{
edge[ne].v=to;
edge[ne].next=head[from];
head[from]=ne++;
//cout<<from<<" "<<to<<endl;
}

bool ok(char *s1, char *s2)
{
for(int i=0; s1[i]!=0; i++)
for(int j=0; s2[j]!=0; j++)
if(s1[i]==s2[j])
return 1;
return 0;
}

void init()
{
ne=0;
memset(head, -1, sizeof(head));
for(int i=0; i<7; i++)
for(int j=0; j<7; j++)
if(ok(s[i], s[j]))
addedge(i, j);
}

bool dfs(int p, int d)
{
if(d==n+1)
{
if(ok(s[f[1]], s[f[n]]))
return 1;
return 0;
}
for(int i=head[p]; i!=-1; i=edge[i].next)
{
int v=edge[i].v;
//cout<<v<<endl;
if(cnt[v])
{
cnt[v]--;
f[d]=v;
if(dfs(v, d+1)) return 1;
cnt[v]++;
}
}
return 0;
}

int main()
{
init();
while(scanf("%d", &n)!=EOF)
{
memset(cnt, 0, sizeof(cnt));
for(int i=1; i<=n; i++)
{
scanf("%s%s", name, like);
int len=strlen(like);
sort(like, like+len);
for(int j=0; j<7; j++)
if(!strcmp(s[j], like))
{
cnt[j]++;
break;
}
}
//缩点
cnt[0]=min(cnt[0], 1);
cnt[1]=min(cnt[1], 1);
cnt[2]=min(cnt[2], 1);
cnt[3]=min(cnt[3], 2);
cnt[4]=min(cnt[4], 2);
cnt[5]=min(cnt[5], 2);
cnt[6]=min(cnt[6], 3);
n=0;
for(int i=0; i<7; i++) n+=cnt[i];
bool flag=dfs(6, 1);
if(flag) puts("Yes");
else puts("No");
}
return 0;
}


 


 

posted on 2011-08-29 17:41  FreeAquar  阅读(330)  评论(3编辑  收藏  举报