【状态压缩DP】函数依赖
|
函数依赖
【样例输入】 首先注意。。那个No candidate key是坑爹的。。最坏都是候选码为ABCD...J。 所以想靠输无解来骗10分的童鞋自重。。
用位集合来表示,A∩B=B,则B∈A。 要注意一个问题,一开始输入的时候可能会有这种问题,AA,BB这之类的,我一开始用的加法就错了,应该或运算
DFS超时一组,其他的秒过,状态空间太大了。如果用枚举就能全过(类似Bellman-Ford,从头扫描到尾多次,直到不能不能再继续延续下去,这种思路比较好。见后面) #include <cstdio>
#include <cstring>
#include <algorithm>
long ans[1050];
char ans2[1050][15];
long top = 0;
long N;long M;
long from[1005];
long to[1005];
bool hash[1050];
bool dfs(long sta)
{
if (sta == (1<<N)-1)
return true;
for (long i=1;i<M+1;i++)
{
if ((sta&from[i])==from[i])
{
if (!hash[sta|to[i]] && (sta|to[i])-sta && !hash[sta|to[i]])
{
hash[sta|to[i]] = true;
if (dfs(sta|to[i]))
{
hash[sta|to[i]] = false;
return true;
}
hash[sta|to[i]] = false;
}
}
}
return false;
}
void Trans(long b)
{
long a = ans[b];
long p = 0;
long s = 0;
do{
if (a & 1)
ans2[b][++s]=p+'A';
p ++;
}while (a>>=1);
}
int cmpare(const void *aa,const void *bb)
{
char * a = (char*) aa;
char * b = (char*) bb;
long len = 0;
while (a[++len] && b[len])
{
if (a[len] > b[len])
return 1;
if (a[len] < b[len])
return -1;
}
if (a[len] > b[len])
return 1;
if (a[len] < b[len])
return -1;
return 0;
}
int main()
{
freopen("dependence.in","r",stdin);
freopen("dependence.out","w",stdout);
scanf("%ld%ld",&N,&M);
for (long i=1;i<M+1;i++)
{
char tmp[30];
char tmp2[15];
tmp[0] = tmp2[0] = 0;
scanf("%s",tmp+1);
long ff=0;long tt=0;
while (tmp[++tmp[0]]-'-'){ff|=(1<<(tmp[tmp[0]]-'A'));}
tmp[0]++;
while (tmp2[++tmp2[0]]=tmp[++tmp[0]]){tt|=(1<<(tmp2[tmp2[0]]-'A'));}
from[i] = ff;
to[i] = tt;
}
for (long i=0;i<(1<<N);i++)
{
bool flag = false;
for (long j=1;j<top+1;j++)
if ((ans[j]&i) == ans[j])
{flag=true;break;}
hash[i] = true;
if (!flag && dfs(i))
ans[++top] = i;
hash[i] = false;
}
printf("%ldn",top);
for (long i=1;i<top+1;i++)
Trans(i);
qsort(ans2+1,top,sizeof(ans2[0]),cmpare);
for (long i=1;i<top+1;i++)
printf("%sn",ans2[i]+1);
return 0;
}
以下是AC程序 #include <cstdlib>
#include <cstdio>
long N;long M;
long from[1005];
long to[1005];
long ans[1050];
char ans2[1050][15];
long top = 0;
void Trans(long x)
{
long p = 0;
long q = 0;
long l = ans[x];
do{
if (l&1)
{
ans2[x][++q]=p+'A';
}
p ++;
}while (l >>= 1);
}
int cmpare(const void* aa,const void* bb)
{
char * a = (char*) aa;
char * b = (char*) bb;
long len = 0;
while (a[++len] && b[len])
{
if (a[len] > b[len]) return 1;
if (a[len] < b[len]) return -1;
}
if (a[len]) return 1;
if (b[len]) return -1;
return 0;
}
int main()
{
freopen("dependence.in",stdout);
scanf("%ld%ld",&M);
for (long i=1;i<M+1;i++)
{
char tmp[30];
tmp[0] = 0;
scanf("%s",tmp+1);
long ff = 0;
while (tmp[++tmp[0]]-'-')
ff |= (1<<(tmp[tmp[0]]-'A'));
tmp[0]++;
long tt = 0;
while (tmp[++tmp[0]])
tt |= (1<<(tmp[tmp[0]]-'A'));
from[i] = ff;
to[i] = tt;
}
for (long Start=0;Start<(1<<N);Start++)
{
bool fflag = false;
for (long i=1;i<top+1;i++)
if ((ans[i]&Start)==ans[i])
fflag = true;
if (fflag) continue;
long sta = Start;
while (sta < (1<<N))
{
bool flag = false;
for (long i=1;i<M+1;i++)
{
if ((sta|to[i])!=sta && (sta&from[i])==from[i])
{
sta |= to[i];
flag = true;
}
}
if (!flag) break;
}
if (sta == (1<<N)-1)
ans[++top] = Start;
}
for (long i=1;i<top+1;i++)
{
Trans(i);
}
qsort(ans2+1,cmpare);
printf("%ldn",top);
for (long i=1;i<top+1;i++)
{
printf("%sn",ans2[i]+1);
}
return 0;
}
(编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
