24h購物| | PChome| 登入
2013-06-29 22:07:40| 人氣1,352| 回應0 | 上一篇 | 下一篇

[UVA][最短路] 11492 - Babel

推薦 0 收藏 0 轉貼0 訂閱站台


 Babel 

The Problem

John and Mary are brothers, and are enthusiastic about their courses on foreign languages. Each of the brothers is taking several language courses. When they get home they comment on grammar, vocabulary, culture of the different countries and so on. In one of those conversations they realized some words are common to more than one language, even though the words may have different meanings in the languages. For example, the word "amigo" exists in Portuguese and Spanish and has the same meaning, while "date" is a word that exists in English and French and may have different meanings, since "date" is also a fruit, besides meaning a calendar date. On the other hand, "red" in Spanish is a network, while in English it is a color.

Thrilled by these findings, the brothers decided to write in a notepad all words in common they could think of, associating each word to a pair of languages. Observant and smart, John proposed a challenge to Mary: given one language to start and one language to finish, write down a sequence of words such that the first word is included in the vocabulary of the start language, and the last word is included in the vocabulary of the finish language. Two adjacent words in the sequence must be in the vocabulary of the same language. For example, if the start language is Portuguese and the finish language is French, Mary could write the sequence "amigo actual date" (Portuguese/Spanish, Spanish/English, English/French).

To John's surprise, Mary solved the problem rather easily. Annoyed by his sister's success, he decided to make the problem more difficult: Mary must find a solution in which the sequence has the smallest number of letters in total (not counting spaces between words), and, besides, two consecutive words must not have the same initial letter.

Note that the previous solution is now invalid, as "amigo" and "actual" share the same initial letter. It is possible, however, to find another solution, "amigo red date", with a total length equal to 12.

John did an extensive research on the Internet and compiled an enormous list of words, and challenged Mary to solve the problem. As there may be more than one solution, he asked her to answer if there is a solution, and in that case to answer the number of letters in the best solution. Can you help Mary?

The Input

The input contains several test cases. The first line of a test case contains one integer M (1 ≤ M ≤ 2000), representing the total number of words compiled by John. The second line contains two distinct strings O and D, separated by one space, indicating respectively the start language and the finish language. Each of the next M lines contains three strings I1, I2 and P, separated by one space, representing respectively two languages and one word in common between both languages (I1 and I2 are always distinct). All strings will have length at least 1 and at most 50, and will be composed of lower case letters only. The same pair of languages may have several words associated to it, but a word P will be never repeated in a test case.

The end of input is indicated by a line containing only one zero.

The Output

For each test case in the input, your program must print a line with a single integer, the length of the shortest sequence that satisfies John's restrictions, or the word "impossivel" (lowercase, meaning "impossible" in Portuguese) in case it is not possible.

Sample Input

4
portugues frances
ingles espanhol red
espanhol portugues amigo
frances ingles date
espanhol ingles actual
4
portugues alemao
ingles espanhol red
espanhol portugues amigo
frances ingles date
espanhol ingles actual
6
portugues frances
ingles espanhol red
espanhol portugues amigo
frances ingles date
frances espanhol la
portugues ingles a
espanhol ingles actual
0

Sample Output

12
impossivel
5

題目描述:
天殺的, 看了好久才明白。
求一個最短的序列, 相鄰的單字有在同一種語言中被定義, 且相鄰兩個單字不可以擁有同一個首字母。
會給定起始要求的語言 以及 目標結束的語言, 以及一個單字在哪兩個語言中被定義。

題目解法:
轉換成最短路徑的思路即可, 但對於每個節點多了一個屬性, 
上次是接什麼字母, 要避免接下來接相同的字母。
下面是用 spfa 的方式去更新
#include <stdio.h>
#include <string.h>
#include <map>
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
struct E {
    int to, fl, len;//to, first letter, length
};
vector<E> g[5005];
int main() {
    int n, i, j, k;
    char O[105], D[105], I1[105], I2[105], word[105];
    while(scanf("%d", &n) == 1 && n) {
        for(i = 0; i < 5000; i++)
            g[i].clear();
        map<string, int> LANG;
        int lsize = 0;
        scanf("%s %s", &O, &D);
        LANG[O] = ++lsize, LANG[D] = ++lsize;
        while(n--) {
            scanf("%s %s %s", &I1, &I2, &word);
            int &x1 = LANG[I1];
            int &x2 = LANG[I2];
            if(x1 == 0) x1 = ++lsize;
            if(x2 == 0) x2 = ++lsize;
            E tmp;
            tmp.to = x2, tmp.fl = word[0]-'a', tmp.len = strlen(word);
            g[x1].push_back(tmp);
            tmp.to = x1;
            g[x2].push_back(tmp);
        }
        int dist[5005][26], inq[5005][26];
        memset(dist, 63, sizeof(dist));
        memset(inq, 0, sizeof(inq));
        queue<int> Qn, Ql;
        dist[1][0] = 0;
        Qn.push(1), Ql.push(0);
        while(!Qn.empty()) {
            int tn = Qn.front();
            int tl = Ql.front();
            Qn.pop(), Ql.pop();
            inq[tn][tl] = 0;
            for(vector<E>::iterator it = g[tn].begin();
                it != g[tn].end(); it++) {
                if(it->fl != tl || tn == 1) {
                    if(dist[it->to][it->fl] > dist[tn][tl] + it->len) {
                        dist[it->to][it->fl] = dist[tn][tl] + it->len;
                        if(inq[it->to][it->fl] == 0) {
                            Qn.push(it->to);
                            Ql.push(it->fl);
                            inq[it->to][it->fl] = 1;
                        }
                    }
                }
            }
        }
        int ret = 0xfffffff;
        for(i = 0; i < 26; i++)
            ret = min(ret, dist[2][i]);
        if(ret == 0xfffffff)
            puts("impossivel");
        else
            printf("%d\n", ret);
    }
    return 0;
}

台長: Morris
人氣(1,352) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: UVA |
此分類下一篇:[UVA] 11718 - Fantasy of a Summation
此分類上一篇:[UVA] 11459 - Snakes and Ladders

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文