【JZOJ3852】【spfa判负环】【NOIP2014八校联考第2场第2试9.28】单词接龙(words)
2017-01-14 22:26
423 查看
Description
Bsny从字典挑出N个单词,并设计了接龙游戏,只要一个单词的最后两个字母和另一个单词的前两个字母相同,那么这两个单词就可以有序的连接起来。Bsny想要知道在所给的所有单词中能否按照上述方式接龙组成一个单词环(可能是多个),若能,求所有环的环中单词平均长度最大值。
Data Constraint
20%的数据:n≤20;70%的数据:n≤1000;
100%的数据:n≤100000,每个单词长度不超过1000。输入数据比较大,C/C++的同学用scanf输入。
Solution
相信大家都很容易想到将前2个和后2个连边。(反正我是在想了1个小时后才想到的……)然后现在问题来了,怎样选边让它平均值最大?我们想到了二分。显然我们二分出一个值mid后,将所右边都减去一个mid,跑一个spfa最长路,若跑出一个环则为合法,往上走,否则往下走。[b]解释一下[/b]
因为我们跑的是最长路,所以当一个环的所有边的和为负数时,他是不可能让到达每个点的权值变得更大的,所以就不可能构成一个环重复跑,也就是说spfa跑最长路跑出的环一定为一个合法的正数环。
[b]那么spfa怎样判环呢[/b]
跑spfa的时候,假设一个点在队列中出现的次数的顶点个数,那么图中一定存在一个环。
Code
#include<iostream> #include<cmath> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; const int maxn=2e6+5; int first[maxn],last[maxn],next[maxn],v[4000000],bz[maxn],bz2[maxn],b[maxn]; int n,i,t,j,k,x,y,num,p,c[1000][1000]; double l,r,mid,value[maxn],d[maxn],xx; char s[maxn]; bool bz1; void lian(int x,int y,int z){ last[++num]=y;next[num]=first[x];first[x]=num;value[num]=z; } bool spfa1(){ int i=0,j=1,t,k,l,x,y; for (k=1;k<=27*27;k++) d[k]=-100000000000; memset(bz2,0,sizeof(bz2)); d[v[1]]=0;bz[v[1]]=1;bz2[v[1]]=1; while (i<j){ x=v[++i]; for (t=first[x];t;t=next[t]){ if (d[x]+value[t]<=d[last[t]]) continue; d[last[t]]=d[x]+value[t]; if (!bz2[last[t]]){ v[++j]=last[t],bz2[v[j]]++,bz[v[j]]++; if (bz[v[j]]>p)return 1; } } bz2[x]=0; } return 0; } bool spfa(){ int i=0,j=1,t,k,l,x,y;memset(bz,0,sizeof(bz)); for (k=1;k<=27*27;k++) if (b[k] && !bz[k]){ v[1]=k;t=spfa1(); if (t) return t; } return 0; } int main(){ //freopen("data.in","r",stdin); scanf("%d\n",&n); for (i=1;i<=n;i++){ scanf("%s\n",s+1); x=(s[1]-96)*27+s[2]-96;t=strlen(s+1); y=(s[t-1]-96)*27+s[t]-96; c[x][y]=max(c[x][y],t); if (!b[x]) p++;if (!b[y]) p++; b[x]=b[y]=1; } for (i=1;i<=27*27;i++) for (j=1;j<=27*27;j++) if (c[i][j]) lian(i,j,c[i][j]); l=1; r=1000; while (r-l>0.001){ mid=(l+r)/2;xx=mid; for (i=1;i<=n;i++) value[i]-=mid; if (spfa()) l=mid; else r=mid; for (i=1;i<=n;i++) value[i]+=xx; } if (l>1) printf("%.2lf\n",l); else printf("No solution.\n"); }
相关文章推荐
- JZOJ 3852. 【NOIP2014八校联考第2场第2试9.28】单词接龙(words)
- 【JZOJ3852】【NOIP2014八校联考第2场第2试9.28】单词接龙(words)
- 【NOIP2014八校联考第2场第2试9.28】单词接龙
- JZOJ 3853. 【NOIP2014八校联考第2场第2试9.28】帮助Bsny(help)
- 【JZOJ3854】【NOIP2014八校联考第2场第2试9.28】分组(group)
- 【JZOJ3853】【NOIP2014八校联考第2场第2试9.28】帮助Bsny(help)
- 【JZOJ3853】【NOIP2014八校联考第2场第2试9.28】帮助Bsny(help)
- 【NOIP2014八校联考第2场第2试】单词接龙
- {题解}[jzoj3853]【NOIP2014八校联考第2场第2试9.28】帮助Bsny(help)
- 【NOIP2014八校联考第2场第2试9.28】帮助Bsny(help)
- 【NOIP2014八校联考第2场第2试9.28】分组(group)
- 【NOIP2014八校联考第2场第2试9.28】分组(group)
- 【NOIP2014八校联考第2场第2试】帮助Bsny
- JZOJ 3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- 【JZOJ3870】【NOIP2014八校联考第4场第1试10.19】单词检索(search)
- 【JZOJ3875】【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- [jzoj]3874. 【NOIP2014八校联考第4场第2试10.20】准备复赛(exam)(树形DP+组合数)
- JZOJ 3870. 【NOIP2014八校联考第4场第1试10.19】单词检索(search)
- [jzoj]3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)(图论题,构树+缩点+LCA+并查集)
- JZOJ3870. 【NOIP2014八校联考第4场第1试10.19】单词检索(search)