URAL 1741 Communication Fiend(最短路径)

Description

Kolya has returned from a summer camp and now he's a real communication fiend. He spends all his free time on the Web chatting with his friends via ICQ. However, lately the protocol of this service was changed once again, and Kolya's client stopped working. Now, in order to communicate with his friends again, Kolya has to upgrade his client from version 1 to version n.
Kolya has found m upgrade programs on the Web. The i-th program upgrades the client from version xi to version yi and its size is dimegabytes. Each program can be installed on the corresponding version of the client only; it can't be installed on either earlier or later versions.
The first version, which is currently installed on Kolya's computer, is licensed, and many of the upgrade programs are pirate copies. If a pirate upgrade program is used, the client will always be pirated after that, whatever upgrade is used later. Some of the licensed upgrade programs can be installed on a pirate version of the client, and some of them can't. All the pirate upgrade programs can be installed on both licensed and pirate versions of the client.
Kolya is missing his friends very much, so he wants to download the necessary upgrade programs as soon as possible. Unfortunately, his Web connection is not very fast. Help Kolya determine the minimal total traffic volume necessary for upgrading the client from version 1 to version n. Kolya doesn't care if the final version n of his client is licensed or not.

Input

The first line contains space-separated integers n and m (2 ≤ n ≤ 104; 1 ≤ m ≤ 104).
Each of the following m lines describes one upgrade program in the form “xi yi di si”. Here, si is the type of the program: “Pirated”, “Cracked”, or “Licensed”. A cracked upgrade program is a licensed program that can be installed on a pirate version of the client, and a licensed program can't be installed on a pirate version. The numbers xi and yi mean that the program is installed on version xi of the client and upgrades it to version yi. The number di is the size of the program in megabytes (1 ≤ xi < yi ≤ n; 1 ≤ di ≤ 106). The data in each line are separated with exactly one space.

Output

If Kolya can upgrade the client from version 1 to version n, output “Online” in the first line and the minimal necessary total incoming traffic volume in the second line.
If it is impossible to upgrade the client, output “Offline”.

 

题目大意:有一个软件,要从1升级到n。每个升级有一个花费,用了P之后就不能再用L,求最小花费。

思路:正解是DP?不管。我们用最短路。建双层图,对于a→b L,在第一层建一条边。对于a→b P,从第一层的a建一条边到第二层的b,再从第二层的a建一条边到第二层的b。对于a→b C,第一层建一条边,第二层建一条边。再从第一层的n建一条边到第二层的n,费用为0。那么就保证了走过了P之后不会再走L,用SPFA求个最短路圆满解决。个人认为比D好写多了。我们要把图论发扬光大O(∩_∩)O~

 

代码(31MS):

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <queue>
 6 using namespace std;
 7 typedef long long LL;
 8 
 9 const int MAXN = 20010;
10 const int MAXE = MAXN * 2;
11 
12 int head[MAXN];
13 int to[MAXE], next[MAXE], cost[MAXE];
14 int n, m, st, ed, ecnt;
15 
16 void init() {
17     memset(head, 0, sizeof(head));
18     ecnt = 1;
19 }
20 
21 void add_edge(int u, int v, int c) {
22     to[ecnt] = v; cost[ecnt] = c; next[ecnt] = head[u]; head[u] = ecnt++;
23     //printf("%d->%d %d\n", u, v, c);
24 }
25 
26 char s[22];
27 
28 void input() {
29     scanf("%d%d", &n, &m);
30     int a, b, c;
31     for(int i = 0; i < m; ++i) {
32         scanf("%d%d%d%s", &a, &b, &c, s);
33         if(*s == 'P') {
34             add_edge(a, b + n, c);
35             add_edge(a + n, b + n, c);
36         }
37         if(*s == 'L') {
38             add_edge(a, b, c);
39         }
40         if(*s == 'C') {
41             add_edge(a, b, c);
42             add_edge(a + n, b + n, c);
43         }
44     }
45     add_edge(n, n + n, 0);
46     st = 1, ed = 2 * n;
47 }
48 
49 LL dis[MAXN];
50 bool vis[MAXN];
51 
52 void SPFA() {
53     memset(dis, 255, sizeof(dis));
54     memset(vis, 0, sizeof(vis));
55     queue<int> que; que.push(st);
56     dis[st] = 0;
57     while(!que.empty()) {
58         int u = que.front(); que.pop();
59         vis[u] = false;
60         for(int p = head[u]; p; p = next[p]) {
61             int &v = to[p];
62             if(dis[v] == -1 || dis[v] > dis[u] + cost[p]) {
63                 dis[v] = dis[u] + cost[p];
64                 if(!vis[v]) que.push(v);
65                 vis[v] = true;
66             }
67         }
68     }
69 }
70 
71 void output() {
72     if(dis[ed] == -1) puts("Offline");
73     else {
74         puts("Online");
75         cout<<dis[ed]<<endl;
76     }
77 }
78 
79 int main() {
80     init();
81     input();
82     SPFA();
83     output();
84 }
View Code

 

posted @ 2013-08-29 21:37  Oyking  阅读(257)  评论(0编辑  收藏  举报