GYM 100030 F. Magic Chains(hash+bfs)

来源:互联网 发布:java投票系统源码 编辑:程序博客网 时间:2024/06/14 07:09

Description
给出n个长度相同的字符串,对应位置只相差一个字母的字符串可以互通,距离为1,问第一个字符串和第n个字符串是否互通,如果互通则输出最短路径,否则输出FALL
Input
第一行一整数n表示字符串数量,之后n个长度不超过10的长度相等的只由小写字母组成的字符串(2<=n<=60000)
Output
如果第一个和最后一个字符串互通则输出最短路径,否则输出FALL
Sample Input
7
voda
yoda
vina
boda
vona
beda
vino
Sample Output
4
voda
vona
vina
vino
Solution
暴力bfsT了,加个hash就行
Code

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>#include<set>#include<ctime>using namespace std;typedef long long ll;#define INF 0x3f3f3f3f#define maxn 66666#define mod 10000007int n,pre[maxn],dis[maxn],vis[maxn];string s[maxn]; queue<int>que;vector<int>ans;struct edge{    ll v;    int id,next;}g[maxn];int tot,head[mod];int H[11][33];ll p[11],a[maxn];void init(){    p[0]=1;    for(int i=1;i<10;i++)p[i]=p[i-1]*26ll;    for(int i=0;i<10;i++)        for(int j=0;j<26;j++)            H[i][j]=rand();    tot=0;    memset(head,-1,sizeof(head));}ll deal(string s){    ll ans=0;    for(int i=0;i<s.size();i++)ans+=p[i]*(s[i]-'a');    return ans;}int hash(string s){    int ans=0;    for(int i=0;i<s.size();i++)ans=(ans+H[i][s[i]-'a'])%mod;    return ans;}void add(int x){    int temp=hash(s[x]);    g[tot].v=a[x];    g[tot].id=x;    g[tot].next=head[temp];    head[temp]=tot++;}int query(int h,ll v){    for(int i=head[h];~i;i=g[i].next)        if(g[i].v==v)return g[i].id;    return 0;}void bfs(){    while(!que.empty())que.pop();    for(int i=2;i<=n;i++)vis[i]=0,dis[i]=INF;    vis[1]=1,dis[1]=0,pre[1]=0;    que.push(1);    int len=s[1].size();    string c;    while(!que.empty())    {        int now=que.front();que.pop();        if(now==n)break;        c=s[now];        int h=hash(c);        ll v=a[now];        for(int i=0;i<len;i++)            for(int j=0;j<26;j++)                if(j+'a'!=c[i])                {                    h-=H[i][c[i]-'a'],h+=H[i][j];                    v-=p[i]*(c[i]-'a'),v+=p[i]*j;                    int t=query(h,v);                    h+=H[i][c[i]-'a'],h-=H[i][j];                    v+=p[i]*(c[i]-'a'),v-=p[i]*j;                    if(!t||vis[t])continue;                    vis[t]=1;                    que.push(t);                    dis[t]=dis[now]+1;                    pre[t]=now;                    if(t==n)return ;                }    }}int main(){    freopen("input.txt","r",stdin);    freopen("output.txt","w",stdout);    init();    while(~scanf("%d",&n))    {        for(int i=1;i<=n;i++)        {            cin>>s[i];            a[i]=deal(s[i]);            add(i);        }        bfs();        if(dis[n]==INF)printf("FAIL\n");        else        {            printf("%d\n",dis[n]+1);            ans.clear();            int now=n;            while(1)            {                ans.push_back(now);                now=pre[now];                if(!pre[now])break;            }            cout<<s[1]<<endl;            for(int i=ans.size()-1;i>=0;i--)cout<<s[ans[i]]<<endl;        }    }    return 0;}
0 0