http://poj.org/problem?id=2679

Adventurous Driving
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 1596   Accepted: 455

Description

After a period of intensive development of the transportation infrastructure, the government of Ruritania decides to take firm steps to strengthen citizens' confidence in the national road network and sets up a compensation scheme for adventurous driving (CSAD). Those driving on a road with holes, bumps and other entertaining obstacles get compensation; those driving on a decent road pay tax. These compensations and taxes are obtained and paid in cash on entry on each road and depend on the entry point on the road. What you get and pay driving on a road from A to B may be different from what you get and pay driving on the same road from B to A. The Ruritarian authorities call fee the amount of money paid as tax or obtained as compensation on entry on a road. A positive fee is a tax; a negative fee stands for compensation. 
John Doe plans to take advantage of CSAD for saving money he needs to repair his old car. When driving from A to B, John follows a path he calls optimal: a path that is rewarding and has the minimal length out of the paths with the minimal weight from A to B. In John's opinion, a path is rewarding if all the roads in the path are rewarding, and a road (X,Y) is rewarding if it has the minimal entry fee out of the roads leaving X. The weight of a path is the sum of the entry fees paid along the path. The length of a path cumulates the length of the roads in the path. The problem is helping John to compute the weight and the length of an optimal path from A to B on a given map. 
For example, on the illustrated road map vertices designate cities and edges stand for roads. The label fuv[L]fvu of the road (u,v) shows the fee fuv for driving from u to v, the fee fvu for driving from v to u, and the length L of the road. The path (0,2,4,3,5) from 0 to 5 is optimal: it is rewarding, has weight 2 (-1+3+0+0) and length 50 (5+10+5+30). The path (0,1,4,3,5), although rewarding and of weight 2, has length 51. The path (0,3,5) has weight 0 and length 20 but it is not rewarding.

Input

Write a program that reads several data sets from a text file. Each data set encodes a road map and starts with four integers: the number 1<=n<=1100 of towns on the map, the number 0<=m<=5000 of roads, the departure town 0<=A<=n-1, and the destination town 0<=B<=n-1. Follow m data quintuples (u,v,fuv[L]fvu), where u and v are town identifiers (integers in the range 0..n-1), 100<=fuv, fvu<=100 are integer fees for driving on the road (u,v), and 1<=L<=100 is the integer length of the road. The quintuples may occur in any order. Except the quintuples, which do not contain white spaces, white spaces may occur freely in input. Input data terminate with an end of file and are correct.

Output

For each data set, the program prints – from the beginning of a line – the weight and the length of an optimal path, according to John's oppinion, from A to B. If there is no optimal path from A to B the text VOID is printed. If the weight of the optimal path from A to B has no lower bound the text UNBOUND is printed.

Sample Input

3 3 0 2 (0,1,0[1]0) (0,2,1[1]0) (1,2,1[1]0)
3 3 0 2 (0,1,-1[1]1) (0,2,0[1]0) (1,2,0[1]1)
7 11 0 5 (0,1,-1[6]4) (0,2,-1[5]4) (0,3,0[1]0) (1,4,3[10]1)
(2,4,3[10]1) (3,4,0[5]0) (3,5,0[30]0) (3,5,1[20]0)
(4,6,0[3]1) (6,5,1[8]0) (6,6,0[2]-1)

Sample Output

VOID
UNBOUND
2 50

Hint

An input/output sample is in the table above. The first data set encodes a road map with no optimal path from 0 to 2. The second data set corresponds to a map whose optimal path from 0 to 2 has an unbound weight. The third data set encodes the road map shown in the above figure.
 
题意:给出一个有向图,每条边有一个费用和长度。给出一个起点一个终点。要求从起点走到终点,每个点的出边必须走费用最小的或者并列最小的,如果按照要求不能走到终点,就输出VOID。然后如果走过的路费用可以无限小,那么就输出 BOUND,否则就计算从起点到终点的最小费用和最小长度,费用最小优先,同样小就长度最小优先。
 
思路:这题一开始看不懂题意,觉得貌似挺水的,看懂题意后一直在第三个样例跑成负环,后来从别人那里才知道这题是要从起点到终点的路径判断,而平时写的是对于整个图判断。首先把每个点最小费用的出边记录下来,把大于这个最小费用的出边删除,这样的图才符合条件。因为要判断从起点到终点的路径是否有负环,平时写的都是对于整个图的判断负环,所以要建立一个反向图,跑一下DFS,用一个vis数组记录从终点跑出去可以经过哪些点,如果不可以经过的话,一定是不会出现在路径上的,那么就删除这些点之后跑SPFA就可以判断负环了,如果不是负环就可以输出最小的 fee 和 dis。
 
这里学习到好多vector的东西。。
 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define INF 0x3f3f3f3f
using namespace std;
#define N 1110
struct edge
{
int l, w, v;
edge () {}
edge (int v, int w, int l) : v(v), w(w), l(l) {}
};
int st, ed, lfee[N], vis[N], dis[N], fee[N], cnt[N], n, m;
vector <vector<edge> > G, R;
//就是vector<edge> G[N]; void add(vector<vector<edge> > &G, int u, int v, int w, int l)
{
G[u].push_back(edge(v, w, l));
} //删除不是最小费用的边
void edge_clear()
{
for(int i = ; i < n; i++) {
for(vector<edge>::iterator p = G[i].begin(); p != G[i].end(); ) {
if(p->w > lfee[i]) {
p = G[i].erase(p);
} else {
p++;
}
}
}
} //删除从起点到终点不会走过的点
void node_clear()
{
for(int i = ; i < n; i++) {
if(!vis[i]) {
G[i].clear();
continue;
}
for(vector<edge>::iterator p = G[i].begin(); p != G[i].end(); ) {
if(!vis[p->v]) {
p = G[i].erase(p);
} else {
p++;
}
}
}
} //将图翻转
void reg()
{
R = vector<vector<edge> > (n);
for(int i = ; i < n; i++) {
for(vector<edge>::iterator p = G[i].begin(); p != G[i].end(); p++) {
add(R, p->v, i, p->w, p->l);
}
}
} //标记从终点走出去可以经过哪些点
void dfs(int u)
{
vis[u] = ;
for(int i = ; i < R[u].size(); i++) {
int v = R[u][i].v;
if(!vis[v]) dfs(v);
}
} bool spfa()
{
for(int i = ; i <= n; i++) {
dis[i] = INF; fee[i] = INF;
}
memset(vis, , sizeof(vis));
memset(cnt, , sizeof(cnt));
dis[st] = ;
fee[st] = ;
vis[st] = ;
queue <int> que;
while(!que.empty()) que.pop();
que.push(st);
while(!que.empty()) {
int u = que.front(); que.pop();
cnt[u]++;
if(cnt[u] > n) return false;
vis[u] = ;
for(int i = ; i < G[u].size(); i++) {
int v = G[u][i].v, w = G[u][i].w, l = G[u][i].l;
if(fee[v] >= fee[u] + w) {
if(fee[v] > fee[u] + w) {
fee[v] = fee[u] + w;
dis[v] = dis[u] + l;
if(!vis[v]) {
vis[v] = ;
que.push(v);
}
} else if(dis[v] > dis[u] + l) {
dis[v] = dis[u] + l;
if(!vis[v]) {
vis[v] = ;
que.push(v);
}
}
}
}
}
} int main()
{
while(~scanf("%d%d%d%d", &n, &m, &st, &ed)) {
memset(lfee, INF, sizeof(lfee));
G.clear(); R.clear();
G = vector<vector<edge> > (n);
for(int i = ; i < m; i++) {
int u, v, uv, vu, l;
scanf(" (%d,%d,%d[%d]%d)", &u, &v, &uv, &l, &vu);
add(G, u, v, uv, l);
add(G, v, u, vu, l);
if(lfee[u] > uv) lfee[u] = uv;
if(lfee[v] > vu) lfee[v] = vu;
//记录出边的最小的费用
} memset(vis, , sizeof(vis));
edge_clear();
reg();
dfs(ed);
if(!vis[st]) {
printf("VOID\n");
continue;
}
node_clear();
bool flag = spfa();
if(!flag) printf("UNBOUND\n");
else printf("%d %d\n", fee[ed], dis[ed]);
}
return ;
}
 

POJ 2679:Adventurous Driving(SPFA+DFS)的更多相关文章

  1. 【PAT甲级】1030 Travel Plan (30 分)(SPFA,DFS)

    题意: 输入N,M,S,D(N,M<=500,0<S,D<N),接下来M行输入一条边的起点,终点,通过时间和通过花费.求花费最小的最短路,输入这条路径包含起点终点,通过时间和通过花费 ...

  2. 【PAT甲级】1018 Public Bike Management (30 分)(SPFA,DFS)

    题意: 输入四个正整数C,N,S,M(c<=100,n<=500),分别表示每个自行车站的最大容量,车站个数,此次行动的终点站以及接下来的M行输入即通路.接下来输入一行N个正整数表示每个自 ...

  3. 题目1008:最短路径问题(SPFA算法)

    问题来源 http://ac.jobdu.com/problem.php?pid=1008 问题描述 给定一个G(V,E)有向图,起点s以及终点t,求最短路径. 问题分析 典型的单源最短路径问题,可以 ...

  4. POJ 2796:Feel Good(单调栈)

    http://poj.org/problem?id=2796 题意:给出n个数,问一个区间里面最小的元素*这个区间元素的和的最大值是多少. 思路:只想到了O(n^2)的做法. 参考了http://ww ...

  5. POJ 3318:Matrix Multiplication(随机算法)

    http://poj.org/problem?id=3318 题意:问A和B两个矩阵相乘能否等于C. 思路:题目明确说出(n^3)的算法不能过,但是通过各种常数优化还是能过的. 这里的随机算法指的是随 ...

  6. 【PAT甲级】1003 Emergency (25 分)(SPFA,DFS)

    题意:n个点,m条双向边,每条边给出通过用时,每个点给出点上的人数,给出起点终点,求不同的最短路的数量以及最短路上最多能通过多少人.(N<=500) AAAAAccepted code: #in ...

  7. POJ 1200:Crazy Search(哈希)

    Crazy Search Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 32483   Accepted: 8947 Des ...

  8. 【题解】洛谷P2296 [NOIP2014TG] 寻找道路(SPFA+DFS)

    题目来源:洛谷P2296 思路 一开始看还以为是一道水题 虽然本来就挺水的 本道题的难点在于如何判断是否路径上的点都会直接或者间接连着终点 我们需要在一开始多建一个反向图 然后从终点DFS回去 把路径 ...

  9. PAT (Advanced Level) Practise 1003 Emergency(SPFA+DFS)

    1003. Emergency (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue As an emerg ...

随机推荐

  1. html5中 table数据导出到excel文件

    JS代码: /** * table数据导出到excel * 形参 table : tableId ; * sheetName : 工作薄名 * fileName : 文件名 * linkId :隐藏的 ...

  2. wpf窗体定位

    原文:wpf窗体定位 据WPF外包小编了解,通常,不需要在屏幕上明确定位窗口.而是简单地将WindowState属性设置为Normal,并忽略其他所有细节.另一方面,很少会将WindowStartup ...

  3. WPF 简单打印

    <Window x:Class="_096基本打印.MainWindow"        xmlns="http://schemas.microsoft.com/w ...

  4. PySide——Python图形化界面入门教程(四)

    PySide——Python图形化界面入门教程(四) ——创建自己的信号槽 ——Creating Your Own Signals and Slots 翻译自:http://pythoncentral ...

  5. mage J和Graphpad如何对Western Blot条带灰度分析

    原文 mage J和Graphpad如何对Western Blot条带灰度分析 WB是研究蛋白表达的一个经典方法.对于一些时间点或者是不同组织蛋白表达量的分析就涉及到量的变化.一些凝胶成像软件带有此分 ...

  6. 核心思想:互联网创业十问?(大部分创业者是从学习借鉴成功者起步的,不需要把商业模式考虑完备,失败者没资格说趁着年轻...)4种失败的信号 good

    著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:曹政链接:https://www.zhihu.com/question/20264499/answer/28168079来源: ...

  7. Android零基础入门第81节:Activity数据传递

    在Android开发中,经常要在Activity之间传递数据.前面也学习了Activity和Intent相关基础,接下来一起来学习Activity的数据传递. 一.简介 通过前面的学习知道,Inten ...

  8. Linux命令执行顺序与管道命令

    命令执行顺序控制 顺序执行多条命令:command1;command2;command3... 有选择执行命令:which command1 && command2 || comman ...

  9. How to Capture the Integer-Divide-By-Zero Error in C++(提前定义信号)

    How to Capture the Integer-Divide-By-Zero Error in C++? MANUAL CAPTURE The simple and straightforwar ...

  10. Windows下配置QT OpenCV

    OpenCV-Study:Windows下配置OpenCV 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境: 主机:XP OpenCV版本:2.4 ...