• 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;
            }
    }
  • 相关阅读:
    面向对象第三单元博客作业
    面向对象编程第2次总结(电梯作业)
    面向对象编程第1次总结
    OOP 第四章博客总结
    OO 第三章总结
    OOP 第二章作业总结
    Java 设计模式 -- 代理模式
    ASID 与 MIPS 中 TLB 相关
    Java 锁机制总结
    OOP 第一章作业总结
  • 原文地址:https://www.cnblogs.com/liyexin/p/12708784.html
Copyright © 2020-2023  润新知