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;
        }
}

 

posted @ 2020-04-15 21:53  liyexin  阅读(161)  评论(0编辑  收藏  举报