zoukankan      html  css  js  c++  java
  • Codeforces Beta Round #33 (Codeforces format) B. String Problem(floyd最短路)

    地址:http://codeforces.com/contest/33/problem/B

        很老的题了,今天被学长拉出来,就做做看。

        题意:给出两个字符串,给出n个 a  b  x,表明字符a可以变成b,每次花费为x。问要想把这俩字符串变成一样的,最少花费多少。无法变就输出-1。

        解析:刚开始以为,每次只看同一个位置,能互换就行,洋洋洒洒写了100多行,一直WA7。原来,一个字符,不一定要变成另一个字符串对应位置的那个字符,可以变成其它的,只要保证花费最小就行。所以我们把26个字母之间互换的花费存起来,跑一遍floyd,就得出了两两变化的最小花费,然后每次看一个位置,就遍历26个字符,看同一位置的这俩字符变成同一个字符所需的花费,求最小就可以了。如果最小值得不到更新,就说明这两个字符串没办法变成同样的,输出-1。

    #include<iostream>
    #include<vector>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+10;
    const int inf = 0x3f3f3f3f;
    int mp[28][28];
    char mid[maxn];
    char s1[maxn],s2[maxn];
    int d[28][28];
    void init()
    {
        for(int i= 0;i<26;i++)
            for(int j=0;j<26;j++)
                {
                    if(i==j)
                        mp[i][j]=0;
                    else
                        mp[i][j]=inf;
                }
    }
    void floyd()
    {
        for(int i=0;i<26;i++)
            for(int j=0;j<26;j++)
                d[i][j]=mp[i][j];
        for(int k=0;k<26;k++)
            for(int i=0;i<26;i++)
                for(int j=0;j<26;j++)
                    d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
    }
    int main()
    {
        cin>>s1;
        cin>>s2;
        int len1=strlen(s1),len2=strlen(s2);
        int n;
        cin>>n;
        init();
        char ch1;
        while(n--)
        {
            scanf(" %c",&ch1);
            char ch2;
            int x;
            scanf(" %c %d",&ch2,&x);
            int a=ch1-'a';
            int b=ch2-'a';
            mp[a][b]=min(mp[a][b],x);
        }    
        if(len1!=len2)
        {
            cout<<"-1"<<endl;
            return 0;    
        } 
        floyd();
        int ok=0;
        int tot=0;
        int sum=0;
        for(int i=0;i<len1;i++)
        {
            if(s1[i]==s2[i])
            {
                mid[tot++]=s1[i];
                continue;
            }
            int minn=inf;
            int a=s1[i]-'a';
            int b=s2[i]-'a';
            for(int j=0;j<26;j++)
            {
                int x1=d[a][j];
                int x2=d[b][j];
                if(x1!=inf&&x2!=inf&&minn>(x1+x2))
                {
                    minn=x1+x2;
                    mid[tot]=char('a'+j);
                }
            }
            if(minn==inf)
            {
                ok=1;break;
            }
        //    cout<<minn<<endl;
            tot++;
            sum+=minn;
        }
        if(ok)
            cout<<"-1"<<endl;
        else
            {
                cout<<sum<<endl;
                cout<<mid<<endl;
            }
    }
  • 相关阅读:
    答题技巧总结(高项)
    系统集成 中英文对照 第一季
    系统集成管理项目工程师总结(别人发的 )
    系统集成管理项目工程师总结(别人发的 我觉得很有意思)
    熵、信息增益以及其他
    位运算
    二分查找排序
    在链表中漫游
    Levenshtein距离
    动态规划(dynamic programming)
  • 原文地址:https://www.cnblogs.com/liyexin/p/12708784.html
Copyright © 2011-2022 走看看