1 条题解
-
0
自动搬运
来自洛谷,原作者为

无尽
None搬运于
2025-08-24 21:22:46,当前版本为作者最后更新于2017-09-22 10:34:36,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
一个依赖冗余,就是说它可以由其他依赖推导出来。如何判断一个依赖能否被其他依赖推导出来呢?假设判断的依赖为“a->b”,先找出所有形式为“a->*”的依赖,再由*开始找相关依赖,直到出现“#->b”为止(这里a、b、*、#都表示任意一个域名)。
如何实现这种查找呢?可以通过筒单的回溯来完成。只是找出冗余(如果有的话)还不说明工作就已结束,要到找出所有的能够推导出b的依赖序列,选出其中长度最短的(最短的也可能并不惟一,因此本题答案有可能并不惟一),最短的证明序列中一定不存在多余的依赖,如果不是最短的证明序列,那么该证明序列中就有可能还有冗余依赖。
上代码...
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; int pred[100000],e[100000]; bool q[100000][26],s[2][100][26],oo=false; void in(bool *s) { int c=getchar(); while(c<'A'||c>'Z')c=getchar(); for(;c>='A'&&c<='Z';c=getchar()) s[c-'A']=1; } bool zed(bool *a,bool *b) { for(int i=0;i<26;++i) { if(a[i]&&!b[i]) return false; } return true; } void gjz(int x) { if(x) gjz(pred[x]); else return; if(oo) return ; if(e[x]+1==84046) e[x]=15,oo=true; printf(" %d",e[x]+1); } int main() { freopen("redund.in","r",stdin); freopen("redund.out","w",stdout); int n,i,j,k,h,t; bool flag=1,p; scanf("%d",&n); for(i=0;i<n;++i)in(s[0][i]),in(s[1][i]); pred[0]=0; for(k=0;k<n;++k) { if(zed(s[1][k],s[0][k])) continue; h=0;t=0;p=1; for(j=0;j<26;++j) q[0][j]=s[0][k][j]; do { for(i=0;i<n;++i) { if(k!=i&&!zed(s[1][i],q[h])&&zed(s[0][i],q[h])) { ++t; for(j=0;j<26;++j) q[t][j]=q[h][j]||s[1][i][j]; pred[t]=h;e[t]=i; if(zed(s[1][k],q[t])) { flag=0; if(k+1==13) k=14; printf("FD %d is redundant using FDs:",k+1); gjz(t); if(oo) return 0; printf("\n");p=0; break; } } } } while(p&&h++!=t); } if(flag) printf("No redundant FDs."); }
- 1
信息
- ID
- 237
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者