24h購物| | PChome| 登入
2013-06-18 08:06:44| 人氣424| 回應0 | 上一篇 | 下一篇

[UVA][dp] 10448 - Unique World

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

Problem E
Unique World
Input: standard input
Output: standard output
Time Limit: 4 seconds
Memory Limit: 32 MB

 

Almost everything is unique in Unique world. The unique creature, unika lives in this world. Each unika has its own unique house. All the houses are connected by roads in such a way so that there is exactly one (unique !!) path from one house to another one. More importantly the cost to traverse each road is unique. In a recent observation, Xenique (President of Unique world) found that the costs of all possible paths are not unique and this should not happen in the Unique World. So, he decided that the cost of each path would be unique. To make this, he also decided that unika can traverse same road more than once while going from one house to another one except the last road on the path. But soon or later he was informed that too many traffic jam is being created due to this rule. Xenique called a meeting on this issue.
A young unika, Prognique suggested that they should use minimum number of roads while visiting from one place to another one. He also told that they should use only those roads, which are necessary for the path. And only a computer program can help in this case.

 

Input

The first line of the input file contains a single integer N (0<N<=20) that denotes the number of inputs. Each data set starts with two positive integers n (n < 51), which denotes the number of unika and m, the number of roads in the unique world. Each of next m lines contains three positive integers, the id of unika (Each unika has a unique id between 1 to n) id1,id2 and c . There is a road of traversing cost c connecting the house of these two unika. Next line contains another integer k (1<=k<=20) , the number of queries. Each of next k lines contains three integers the id of the unika of the source and destination houses and the required cost (between 1 and 100000) of this path. Input may contain blank lines.

 

Output

For each data set, if it is possible to traverse the path using the given cost, print "Yes" and the minimum number of roads. Otherwise just print "No". Put a blank line between two consecutive sets of inputs.

 

Sample Input

1
5 4
1 2 2
1 3 3
1 4 4
1 5 5
5
1 2 2
2 3 5
2 3 6
4 5 10
2 4 18

 

Sample Output

Yes 1
Yes 2
No
No

Yes 8


Problem-setter: Md. Kamruzzaman, BUET Sprinters

題目描述:

每條路的花費都唯一,希望從起點到終點指定花費下最少路的使用。

但走的時候只能在必要路上(最短路徑上),然後在抵達終點前一條路上不可重複走。

題目解法:

先做一次最短路徑,得到必要的邊。

但沒想到最短路徑只有一條可能,如果有多種可能的話,比較不好寫。

也不確定題目到底是怎麼描述的。那在此先考慮僅一條最短路徑。

基本就得到最短路徑長與邊的個數。

接著使用 dp,最小化邊的個數得到 dp[cost-最短路徑長]。

更新的方法跟零錢問題很像,而不是01背包問題。

#include <stdio.h>
#include <string.h>
#include <queue>
#include <map>
using namespace std;
struct E {
    int to, v;
    E(int a, int b):
        to(a), v(b) {}
};
vector<E> g[50];
void sol(int st, int ed, int v) {
    int dist[50], inq[50] = {};
    int i, j, k, tn;
    memset(dist, 63, sizeof(dist));
    dist[st] = 0;
    queue<int> Q;
    Q.push(st);
    while(!Q.empty()) {
        tn = Q.front(), Q.pop();
        inq[tn] = 0;
        for(vector<E>::iterator it = g[tn].begin();
            it != g[tn].end(); it++) {
            if(dist[it->to] > dist[tn] + it->v) {
                dist[it->to] = dist[tn] + it->v;
                if(inq[it->to] == 0) {
                    inq[it->to] = 1;
                    Q.push(it->to);
                }
            }
        }
    }
    int dp[100001], dpway[50] = {}, onway = 0;
    memset(dp, 63, sizeof(dp));
    int oo = dp[0];
    dp[0] = 0, dpway[ed] = 1;
    Q.push(ed);
    if(v - dist[ed] < 0) {
        puts("No");
        return;
    }
    while(!Q.empty()) {
        tn = Q.front(), Q.pop();
        onway++;
        for(vector<E>::iterator it = g[tn].begin();
            it != g[tn].end(); it++) {
            if(dist[it->to] + it->v == dist[tn]) {
                if(tn != ed) {
                    for(i = 0; i <= v-dist[ed]; i++) {
                        j = (it->v)*2;
                        dp[i+j] = min(dp[i+j], dp[i]+2);
                    }
                }
                dpway[it->to] += dpway[tn];
                if(inq[it->to] == 0)
                    inq[it->to] = 1, Q.push(it->to);
            }
        }
    }
    if(v-dist[ed] >= 0 && dp[v-dist[ed]] != oo)
        printf("Yes %d\n", dp[v-dist[ed]] + onway-1);
    else
        puts("No");
}
int main() {
    int testcase, n, m;
    int x, y, v, i;
    scanf("%d", &testcase);
    while(testcase--) {
        scanf("%d %d", &n, &m);
        for(i = 0; i < n; i++)
            g[i].clear();
        while(m--) {
            scanf("%d %d %d", &x, &y, &v);
            x--, y--;
            g[x].push_back(E(y, v));
            g[y].push_back(E(x, v));
        }
        scanf("%d", &m);
        while(m--) {
            scanf("%d %d %d", &x, &y, &v);
            x--, y--;
            sol(x, y, v);
        }
        if(testcase)
            puts("");
    }
    return 0;
}
/*
1
5 4
1 2 2
1 3 3
1 4 4
1 5 5
5
1 2 2
2 3 5
2 3 6
4 5 10
2 4 18
*/

台長: Morris
人氣(424) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: UVA |
此分類下一篇:[UVA][時間計算] 10339 - Watching Watches
此分類上一篇:[UVA][格式] 10698 - Football Sort

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