编程练习7(最短路)

A:Frogger(POJ2253)

Description

Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sitting on another stone. He plans to visit her, but since the water is dirty and full of tourists’ sunscreen, he wants to avoid swimming and instead reach her by jumping.
Unfortunately Fiona’s stone is out of his jump range. Therefore Freddy considers to use other stones as intermediate stops and reach her by a sequence of several small jumps.
To execute a given sequence of jumps, a frog’s jump range obviously must be at least as long as the longest jump occuring in the sequence.
The frog distance (humans also call it minimax distance) between two stones therefore is defined as the minimum necessary jump range over all possible paths between the two stones.

You are given the coordinates of Freddy’s stone, Fiona’s stone and all other stones in the lake. Your job is to compute the frog distance between Freddy’s and Fiona’s stone.

Input

The input will contain one or more test cases. The first line of each test case will contain the number of stones n (2<=n<=200). The next n lines each contain two integers xi,yi (0 <= xi,yi <= 1000) representing the coordinates of stone #i. Stone #1 is Freddy’s stone, stone #2 is Fiona’s stone, the other n-2 stones are unoccupied. There’s a blank line following each test case. Input is terminated by a value of zero (0) for n.

Output

For each test case, print a line saying “Scenario #x” and a line saying “Frog Distance = y” where x is replaced by the test case number (they are numbered from 1) and y is replaced by the appropriate real number, printed to three decimals. Put a blank line after each test case, even after the last one.

Sample Input

2
0 0
3 4

3
17 4
19 4
18 5

0

Sample Output

Scenario #1
Frog Distance = 5.000

Scenario #2
Frog Distance = 1.414

我的代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
int T,num,n,m;
int sal,p;
int i,j,k;
struct Node{
    int x,y;
};
struct edge{
    int u,v;
    double w;
};
const double INF = 1e8;
Node stone[205];
bool visited[205];
double d[205];
double distance(int a, int b){
    return sqrt(double((stone[a].x-stone[b].x)*(stone[a].x-stone[b].x)+(stone[a].y-stone[b].y)*(stone[a].y-stone[b].y)));
}

void init(){
    for (i = 1 ; i <= num; i++) {
        d[i] = INF;
        visited[i] = false;
    }
    d[1] = 0;
    visited[1] = true;
}
void dijstra(){
    int v = 1;
    init();

    for (i = 1 ; i <= num; i++) {
        int min = INF;
        //找到最小的d
        for (j = 1; j <= num; j++) {
            if(!visited[j] && d[j] < min){
                min = d[j];
                v = j;
            }
        }
       //标记为访问过,更新其他点
        visited[v] = true;
        if (v == 2) {
            printf("Scenario #%d\n",T);
            printf("Frog Distance = %.3f\n\n",d[2]);
            return;
        }
        for (j = 1; j <= num ; j++) {
            if (!visited[j] &&  d[j] > max(d[v],distance(v,j))) {
                d[j] = max(d[v],distance(v,j));
            }
        }


    }
}
int main() {
   // freopen("input.txt", "r", stdin);
    T = 0;
    while(scanf("%d",&num)!= EOF && num != 0) {
        T++;
        for (i = 1; i <= num; i++) {
            scanf("%d%d",&stone[i].x,&stone[i].y);
        }
        dijstra();
    }
    return 0;
}

B:Wormholes(POJ3259)

Description

While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way path that delivers you to its destination at a time that is BEFORE you entered the wormhole! Each of FJ’s farms comprises N (1 ≤ N ≤ 500) fields conveniently numbered 1..N, M (1 ≤ M ≤ 2500) paths, and W (1 ≤ W ≤ 200) wormholes.

As FJ is an avid time-traveling fan, he wants to do the following: start at some field, travel through some paths and wormholes, and return to the starting field a time before his initial departure. Perhaps he will be able to meet himself :) .

To help FJ find out whether this is possible or not, he will supply you with complete maps to F (1 ≤ F ≤ 5) of his farms. No paths will take longer than 10,000 seconds to travel and no wormhole can bring FJ back in time by more than 10,000 seconds.

Input

Line 1: A single integer, F. F farm descriptions follow.
Line 1 of each farm: Three space-separated integers respectively: N, M, and W
Lines 2.. M+1 of each farm: Three space-separated numbers ( S, E, T) that describe, respectively: a bidirectional path between S and E that requires T seconds to traverse. Two fields might be connected by more than one path.
Lines M+2.. M+ W+1 of each farm: Three space-separated numbers ( S, E, T) that describe, respectively: A one way path from S to E that also moves the traveler back T seconds.

Output

Lines 1.. F: For each farm, output “YES” if FJ can achieve his goal, otherwise output “NO” (do not include the quotes).

Sample Input

2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8

Sample Output

NO
YES

我的代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const int INF = 1000000000;
int numf,n,m;
int N, M, W;
int i,j;
struct Edge{
    int beg,end;
    int w;
};
int d[505];
Edge edge[7000];
//w表示边数

void init(){
    for (i = 1; i <=N; i++) {
        d[i] = INF;
    }
    d[1] = 0;
}
bool bellman(int w){
    for (i = 1; i <= N; i++) {
        for (j = 1; j <= w; j++) {
            if (d[edge[j].end] > d[edge[j].beg] + edge[j].w ) {
                d[edge[j].end] = d[edge[j].beg] + edge[j].w;
            }
        }
    }
    for (j = 1; j <= w; j++) {
        if (d[edge[j].end] > d[edge[j].beg] + edge[j].w) {
            return false;
        }
    }
    return true;
}
int main() {
    //freopen("input.txt", "r", stdin);
    scanf("%d",&numf);
    while(numf--) {
        init();
        scanf("%d%d%d",&N,&M,&W);
        int k = 1;
        for (i = 1; i <= M; i++) {
            scanf("%d%d%d",&edge[k].beg,&edge[k].end,&edge[k].w);
            k++;
            edge[k].beg = edge[k-1].end;edge[k].end = edge[k-1].beg;edge[k].w = edge[k-1].w;
            k++;
        }
        for (i = 1; i <= W; i++) {
            scanf("%d%d%d",&edge[k].beg,&edge[k].end,&edge[k].w);
            edge[k].w = - edge[k].w;
            k++;
        }
        bool flag = bellman(2*M+W);
        if (!flag) {
            printf("YES\n");
        }else{
            printf("NO\n");
        }
    }
    return 0;
}
<think>嗯,用户问的是《C++ PrimerPlus》第五章编程练习的答案。首先,我需要确认第五章的内容是什么。通常这本书的第五章讲的是循环和关系表达式,主要涉及for循环、while循环、dowhile循环,以及一些控制语句如break、continue,可能还有逻辑运算符的应用。 接下来,用户需要的是编程练习的答案,但直接给出答案可能涉及版权问题,特别是如果原书有配套的答案的话。不过,可能用户只是需要一些示例代码来理解题目怎么做,或者遇到具体的问题需要帮助解决。由于用户没有具体说明是哪一道题,我需要先询问具体的题目内容,或者给出几个常见题目的解答示例,这样既符合用户的需求,又避免侵权问题。 比如,假设第五章的一个练习题是计算用户输入数字的总和及平均值,我可以写一个使用while循环读取输入直到遇到非数字输入的程序。另一个题目可能是使用嵌套循环打印某种图案,比如星号三角形。或者可能涉及到字符输入统计,比如统计空格、换行符的数量等。 另外,我需要确保代码符合C++的标准,并且使用清晰的注释说明每一步的作用。同时,解释代码的结构和逻辑,帮助用户理解如何解决这类问题。例如,在循环控制中,如何正确初始化变量,如何设置终止条件,如何处理输入缓冲等。 可能还需要提醒用户注意常见的错误,比如循环条件设置不当导致死循环,或者变量未初始化导致结果错误。此外,关于输入处理时可能遇到的类型不匹配问题,比如用户输入了非预期的字符导致循环终止,也需要进行适当的错误处理。后,根据用户的需求,提出相关问题,帮助用户进一步巩固第五章的知识点,比如不同循环结构的区别、break和continue的使用场景、逻辑运算符的短路特性等等。这样用户不仅能得到答案,还能深入理解相关概念,提升解决问题的能力。</think>由于《C++ Primer Plus》的练习题受版权保护,我无直接提供官方答案。但我可以为您展示几个典型题目的实现范例,并解释关键知识点。以下是第五章(循环和关系表达式)常见的3个练习类型: --- **示例1:简单计数器** 题目要求:编写程序统计用户输入的空格、换行符总数,直到遇到`#`字符结束 ```cpp #include <iostream> int main() { char ch; int spaces = 0, newlines = 0; std::cout << "Enter characters (# to quit):\n"; while(std::cin.get(ch) && ch != '#') { if(ch == ' ') ++spaces; else if(ch == '\n') ++newlines; } std::cout << "Spaces: " << spaces << "\nNewlines: " << newlines; return 0; } ``` **解释**: - 使用`cin.get()`读取包括空白符的字符 - `while`循环条件同时检查输入状态和终止字符 - 通过字符比较进行计数 --- **示例2:阶乘计算** 题目要求:用户输入数字,程序计算并显示其阶乘 ```cpp #include <iostream> int main() { int n; long long factorial = 1; std::cout << "Enter a positive integer: "; std::cin >> n; for(int i = 1; i <= n; ++i) { factorial *= i; } std::cout << n << "! = " << factorial; return 0; } ``` **解释**: - 使用`for`循环进行迭代乘 - 注意使用`long long`类型防止数值溢出 - 循环变量从1开始递增到n --- **示例3:温度转换表** 题目要求:生成华氏温度到摄氏温度的转换表,步长为5度 ```cpp #include <iostream> #include <iomanip> int main() { std::cout << "Fahrenheit Celsius\n"; std::cout << std::fixed << std::setprecision(1); for(int f = 0; f <= 100; f += 5) { double c = (f - 32) * 5.0 / 9.0; std::cout << std::setw(10) << f << std::setw(10) << c << "\n"; } return 0; } ``` **解释**: - 使用`iomanip`库控制输出格式 - `setw()`设置字段宽度实现对齐 - `setprecision()`控制小数位数 - 温度转换公式的应用 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值