24h購物| | PChome| 登入
2013-06-08 09:18:11| 人氣3,162| 回應0 | 上一篇 | 下一篇

[UVA][負環] 10449 - Traffic

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

Problem F
Traffic
Input: standard input
Output: standard output
Time Limit: 4 seconds

Dhaka city is getting crowded and noisy day by day. Certain roads always remain blocked in congestion. In order that people avoid shortest routes, and hence the crowded roads, to reach destination, the city authority has made a new plan. Each junction of the city is marked with a positive integer (£20) denoting the busyness of the junction. Whenever someone goes from one junction (the source junction) to another (the destination junction), the city authority gets the amount (busyness of destination – busyness of source)3 from the traveler.

The authority has appointed you to find out the minimum total amount that it earns when someone goes from a certain junction (the zero point) to several others.

Input
The first line of each test case contains n (the number of junctions, 0 £ n £ 200) followed by n integers denoting the busyness of the junctions numbered 1 to n in that order. The next line contains r, the number of roads in the city. Each of the next r lines (one for each road) contains two junction-numbers (source, destination) that the corresponding road connects (all roads are unidirectional). The next line contains the integer q, the number of queries. The next q lines each contain a junction-number. Input is terminated by EOF.

Output
For each set of output, print the set # (1, 2, … ) followed by q lines, one for each query, each containing the minimum total earning when one travels from junction 1 (the zero point) to the corresponding junction. However, for the queries that gives less than 3 units of minimum total earning, print a '?'.

Sample Input                 

5 6 7 8 9 10
6
1 2
2 3
3 4
1 5
5 4
4 5
2
4
5
 
Sample Output
Set #1
3
4

(Problem-setter: Mustaq Ahmed, University of Waterloo)

題目描述:

每個交叉口都有其忙碌指數,為了疏通交通,鼓勵用路人從忙碌指數高到低(發錢給用路人),反之向用路人收費,其獎金是"忙碌指數差的三次方"。

問從編號 1 號點到任一的點,其政府可以向這個用路人收多少錢?
-用路人當然想盡量拿獎金,少付錢。因此就是政府只會拿到最少的錢。

題目解法:

題目有一點很奇怪,小於 3 的賺取費用就輸出 '?',只好認定這一點小錢他不太想賺。
題目要檢測負環,這個負環會讓用路人一直賺錢,即要找到圖中所有負環上的點輸出 '?'。

利用 spfa 去判斷負環,當進入 queue 超過 n 次時,那麼這一點就是負環上的點,
Bellman Ford 當然也可以檢測。
找到負環上的點後,其可以到達的點(bfs) 都可以算是 '?' 輸出,必然是賺不到錢的點。


#include <stdio.h>
#include <string.h>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
vector<pair<int, int> > g[205];
int dist[205], n;
void spfa(int st) {
    int inq[205] = {}, tn;
    int cnt[205] = {}, neg[205] = {};
    queue<int> Q;
    dist[st] = 0;
    Q.push(st);
    while(!Q.empty()) {
        tn = Q.front(), Q.pop();
        inq[tn] = 0;
        for(vector<pair<int, int> >::iterator it = g[tn].begin();
            it != g[tn].end(); it++) {
            if(dist[it->first] > dist[tn] + it->second) {
                dist[it->first] = dist[tn] + it->second;
                if(inq[it->first] == 0) {
                    if(++cnt[it->first] >= n+1) {
                        queue<int> nq;
                        nq.push(it->first);
                        neg[it->first] = 1;
                        while(!nq.empty()) {
                            int tn = nq.front();
                            nq.pop();
                            dist[tn] = -0xfffffff;
                            for(vector<pair<int, int> >::iterator it = g[tn].begin();
                                it != g[tn].end(); it++) {
                                if(neg[it->first] == 0) {
                                    neg[it->first] = 1;
                                    nq.push(it->first);
                                }
                            }
                        }
                    }
                    if(neg[it->first] == 0) {
                        Q.push(it->first);
                        inq[it->first] = 1;
                    }
                }
            }
        }
    }
}
int main() {
    int m, C[205];
    int i, j, x, y;
    int cases = 0;
    while(scanf("%d", &n) == 1) {
        for(i = 1; i <= n; i++) {
            scanf("%d", &C[i]);
            dist[i] = 0xfffffff;
            g[i].clear();
        }
        scanf("%d", &m);
        while(m--) {
            scanf("%d %d", &x, &y);
            g[x].push_back(make_pair(y, (C[y]-C[x])*(C[y]-C[x])*(C[y]-C[x])));
        }
        scanf("%d", &m);
        spfa(1);
        printf("Set #%d\n", ++cases);
        while(m--) {
            scanf("%d", &x);
            if(x <= 0 || x > n || dist[x] < 3 || dist[x] == 0xfffffff)
                puts("?");
            else
                printf("%d\n", dist[x]);
        }
    }
    return 0;
}
/*
5 6 7 8 9 10
6
1 2
2 3
3 4
1 5
5 4
4 5
2
4
5
*/

台長: Morris
人氣(3,162) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: UVA |
此分類下一篇:[UVA][MST] 1216 - The Bug Sensor Problem
此分類上一篇:[UVA][積分] 10124 - Subway

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