zoukankan      html  css  js  c++  java
  • 1806. Mobile Telegraphs 夜

    http://acm.timus.ru/problem.aspx?space=1&num=1806

    只要算法对 ural 一般不会卡时间的

    这个题是一个简单的最短路 spfa

    关键在于找边 找边的方法是 对于每一个点 枚举它的所有可能的变化 搜索是否有和变化后的字符串一样的

    搜索的时候既可以用 map  也可以 自己写字典树

    map 写起来简单 不过 字典树效率要高

    注意边的个数 要在 N*50

    代码1:

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<vector>
    #include<set>
    #include<map>
    #include<string>
    #include<queue>
    #include<stack>
    #include <iomanip>
    using namespace std;
    #define LL long long
    const int INF=0x3f3f3f3f;
    const int N=50005;
    int head[N],I;
    struct node
    {
        int j,next,t;
    }side[N*50];
    int cost[N];
    int f[N];
    bool in[N];
    int dist[N];
    char s[N][12];
    stack<int>st;
    struct node1
    {
        int k;
        struct node1 *next[10];
    };
    struct node1 *root;
    void add(int i,int j,int t)
    {//cout<<i<<" "<<j<<" "<<t<<endl;
        side[I].j=j;
        side[I].t=t;
        side[I].next=head[i];
        head[i]=I++;
    }
    int costtime(int i,int j)
    {
        for(int x=0;x<10;++x)
        {
            if(s[i][x]!=s[j][x])
            return cost[x];
        }
        return 0;
    }
    bool spfa(int st,int nd)
    {
        memset(in,false,sizeof(in));
        memset(dist,-1,sizeof(dist));
        queue<int>qt;
        qt.push(st);
        in[st]=true;
        dist[st]=0;
        while(!qt.empty())
        {
            int x=qt.front();qt.pop();
            in[x]=false;
            for(int t=head[x];t!=-1;t=side[t].next)
            {
                int j=side[t].j;
                if(dist[j]==-1||dist[j]>dist[x]+side[t].t)
                {
    
                    dist[j]=dist[x]+side[t].t;
                    f[j]=x;
                    if(!in[j])
                    {
                        in[j]=true;
                        qt.push(j);
                    }
                }
            }
        }
    
        if(dist[nd]==-1)
        return false;
        return true;
    }
    void insert(int x)
    {//cout<<x<<endl;
        struct node1 *w,*t=root;
        for(int i=0;i<10;++i)
        {
            if(t->next[s[x][i]-'0']==NULL)
            {
                w=new node1;
                for(int j=0;j<10;++j)
                w->next[j]=NULL;
                t->next[s[x][i]-'0']=w;
            }
            t=t->next[s[x][i]-'0'];
        }
        t->k=x;
    }
    int Fnum(int x)
    {
        struct node1 *t=root;
        for(int i=0;i<10;++i)
        {
            if(t->next[s[x][i]-'0']==NULL)
            return 0;
            t=t->next[s[x][i]-'0'];
        }
        return t->k;
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            root=new node1;
            for(int i=0;i<10;++i)
            root->next[i]=NULL;
            for(int i=0;i<10;++i)
            scanf("%d",&cost[i]);
            getchar();
            for(int i=1;i<=n;++i)
            {
                gets(s[i]);
                insert(i);
            }
            memset(head,-1,sizeof(head));
            I=0;
            int k;
            for(int i=1;i<=n;++i)
            {
                for(int l=0;l<10;++l)
                {
                    char ctmp=s[i][l];
                    for(char c='0';c<='9';++c)
                    {
                        if(ctmp==c)
                        continue;
                        s[i][l]=c;
                        if((k=Fnum(i)))
                        {
                            s[i][l]=ctmp;
                            add(i,k,costtime(i,k));
                            continue;
                        }
                    }
                    s[i][l]=ctmp;
                }
                for(int l=0;l<10;++l)
                for(int r=l+1;r<10;++r)
                {
                    if(s[i][l]==s[i][r])
                    continue;
                    swap(s[i][l],s[i][r]);
                    if((k=Fnum(i)))
                    {
                        swap(s[i][l],s[i][r]);
                        add(i,k,costtime(i,k));
                        continue;
                    }
                    swap(s[i][l],s[i][r]);
                }
            }
            if(!spfa(1,n))
            printf("-1\n");
            else
            {
                while(!st.empty())
                st.pop();
                int k=n;
                while(k!=1)
                {
                    st.push(k);
                    k=f[k];
                }
                printf("%d\n",dist[n]);
                printf("%d\n",st.size()+1);
                printf("1");
                while(!st.empty())
                {
                    printf(" %d",st.top());
                    st.pop();
                }
                printf("\n");
            }
        }
        return 0;
    }
    

     代码2:

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<vector>
    #include<set>
    #include<map>
    #include<string>
    #include<queue>
    #include<stack>
    #include <iomanip>
    using namespace std;
    #define LL long long
    const int INF=0x3f3f3f3f;
    const int N=50005;
    int head[N],I;
    struct node
    {
        int j,next,t;
    }side[N*50];
    int cost[N];
    map<string,int>mt;
    map<string,int>::iterator it;
    int f[N];
    bool in[N];
    int dist[N];
    string s[N];
    stack<int>st;
    
    void add(int i,int j,int t)
    {//cout<<i<<" "<<j<<" "<<t<<endl;
        side[I].j=j;
        side[I].t=t;
        side[I].next=head[i];
        head[i]=I++;
    }
    int costtime(int i,int j)
    {
        for(int x=0;x<10;++x)
        {
            if(s[i][x]!=s[j][x])
            return cost[x];
        }
        return 10;
    }
    bool spfa(int st,int nd)
    {
        memset(in,false,sizeof(in));
        memset(dist,-1,sizeof(dist));
        queue<int>qt;
        qt.push(st);
        in[st]=true;
        dist[st]=0;
        while(!qt.empty())
        {
            int x=qt.front();qt.pop();
            in[x]=false;
            for(int t=head[x];t!=-1;t=side[t].next)
            {
                int j=side[t].j;
                if(dist[j]==-1||dist[j]>dist[x]+side[t].t)
                {
    
                    dist[j]=dist[x]+side[t].t;
                    f[j]=x;
                    if(!in[j])
                    {
                        in[j]=true;
                        qt.push(j);
                    }
                }
            }
        }
    
        if(dist[nd]==-1)
        return false;
        return true;
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        int n;
        while(cin>>n)
        {
            for(int i=0;i<10;++i)
            cin>>cost[i];
            mt.clear();
            for(int i=1;i<=n;++i)
            {
                cin>>s[i];
                mt[s[i]]=i;
            }
            memset(head,-1,sizeof(head));
            I=0;
            for(int i=1;i<=n;++i)
            {
                s[0]=s[i];
                for(int l=0;l<10;++l)
                {
                    char ctmp=s[i][l];
                    for(char c='0';c<='9';++c)
                    {
                        if(ctmp==c)
                        continue;
                        s[i][l]=c;
                        if((it=mt.find(s[i]))!=mt.end())
                        add(i,it->second,costtime(0,it->second));
                    }
                    s[i][l]=ctmp;
                }
                for(int l=0;l<10;++l)
                for(int r=l+1;r<10;++r)
                {
                    if(s[i][l]==s[i][r])
                    continue;
                    swap(s[i][l],s[i][r]);
                    if((it=mt.find(s[i]))!=mt.end())
                    add(i,it->second,costtime(0,it->second));
                    swap(s[i][l],s[i][r]);
                }
            }
            if(!spfa(1,n))
            cout<<"-1"<<endl;
            else
            {
                while(!st.empty())
                st.pop();
                int k=n;
                while(k!=1)
                {
                    st.push(k);
                    k=f[k];
                }
                cout<<dist[n]<<endl;
                cout<<(st.size()+1)<<endl;
                cout<<"1";
                while(!st.empty())
                {
                    cout<<" "<<st.top();
                    st.pop();
                }
                cout<<endl;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    CLR via C#(11)-无参属性、索引器
    CLR via C#(10)-参数
    C#委托的介绍(delegate、Action、Func、predicate)
    MVC3使用Unity实现接口自动注册
    CLR via C#(09)-扩展方法
    CLR via C#(08)-操作符
    CLR via C#(07)-静态类,分部类
    CLR via C#(06)- 构造器
    VS2010几款超赞的扩展辅助工具总结
    web前端开发随手笔记
  • 原文地址:https://www.cnblogs.com/liulangye/p/2778043.html
Copyright © 2011-2022 走看看