Original question:
Consider yourself lucky! Consider yourself lucky to be still breathing and have fun participating in
This contest. But we apprehend the many of your descendants may not have the this luxury. For, as you
Know, we is the dwellers of one of the most polluted cities on earth. Pollution is everywhere, both in
The environment and in society and our lack of consciousness are simply aggravating the situation.
However, for the time being, we'll consider only a type of pollution-the sound pollution. The
Loudness or intensity level of sound are usually measured in decibels and sound have intensity level 130
Decibels or higher is considered painful. The intensity level of normal conversation is 6065 decibels and
That's heavy traffic is 7080 decibels.
Consider the following city map where the edges refer to streets and the nodes refer to crossings.
The integer on each edge are the average intensity level of sound (in decibels) in the corresponding street.
To get from crossing A to crossing G your may follow the following path:a-c-f-g. In the case
You must is capable of tolerating sound intensity as high as decibels. For the Paths a-b-e-g,
A-b-d-g and a-c-f-d-g you must tolerate respectively, and the decibels of sound intensity.
There is other paths, too. However, it's clear that a-c-f-d-g are the most comfortable path since
It does not demand your to tolerate more than decibels.
In this problem, given a city map you is required to determine the minimum sound intensity level
You must is able to tolerate on order to get from a given crossing to another.
Input
The input may contain multiple test cases.
The first line of all test case contains three integers C (≤100), S (≤1000) and Q (≤10000) where
C indicates the number of crossings (crossings is numbered using distinct integers ranging from 1 to
C), S represents the number of streets and Q is the number of queries.
Each of the next S lines contains three integers:c1,c2 and d indicating so the average sound
Intensity level on the street connecting the Crossings C1and C2 (c1̸= C2) is D decibels.
Each of the next Q lines contains, integers c1and c2 (c1̸= C2) asking for the minimum sound
Intensity level must is able to tolerate on order to get from crossing c1to crossing C2.
The input would terminate with three zeros form C, S and Q.
Output
For each test, the input first output the test Case number (starting from 1) as shown in the
Sample output. Then to each query with the input print a line giving the minimum sound intensity level
(in decibels) must is able to tolerate in order to get from the first to the second crossing in the
Query. If there exists no path between them just print the line "no path".
Print a blank line between consecutive test cases.
Sample Input
7 9 3
1 2 50
1 3 60
2 4 120
2 5 90
3 6 50
4 6 80
4 7 70
5 7 40
6 7 140
1 7
2 6
6 2
7 6 3
1 2 50
1 3 60
2 4 120
3 6 50
4 6 80
5 7 40
7 5
1 7
2 4
0 0 0
Sample Output
Case #1
80
60
60
Case #2
40
No path
80
Main topic:
Give you an no-show graph and then give you a bunch of queries. Each query enters two nodes, a, B, and then asks you to find a path that minimizes the value of the maximum weight within the path from a to a. (Compare around the mouth, carefully translate the original question can be)
See below code for ideas
#include <iostream>
#include <algorithm>
#include <map>
#include <string>
#include <cstring>
#include <sstream>
#include <cstdio>
#include <vector>
using namespace std;
const int maxint = 999999;
int dp [101] [101];
int Map [101] [101];
int low [101];
bool vis [101];
vector <int> vp;
int c, s, q;
void ini ()
{
for (int i = 1; i <= c; i ++)
for (int j = 1; j <= c; j ++)
Map [i] [j] = maxint;
memset (vis, 0, sizeof (vis));
memset (dp, -1, sizeof (dp));
}
struct query
{
int a, b;
};
query que [10001];
void prim (int c)
{
vp.clear ();
int pre, min, pos; // pre represents the node connected to pos, that is, the node found before pos
vis [1] = true;
pos = 1;
pre = 1;
vp.push_back (pos); // First select node 1 as the starting point, node 1 is added to vp
for (int i = 1; i <= c; i ++)
if (i! = pos)
low [i] = Map [pos] [i];
for (int i = 1; i <c; i ++)
{
min = maxint;
min = maxint + 1; // change 1 so that non-connected nodes can be found
for (int j = 1; j <= c; j ++)
if (! vis [j] && min> low [j])
{
min = low [j]; pos = j;
}
dp [pre] [pos] = dp [pos] [pre] = min;
for (int k = 0; k <vp.size (); k ++) // Change 2, every update
dp [pos] [vp [k]] = dp [vp [k]] [pos] = max (dp [vp [k]] [pre], dp [pos] [pre]);
vp.push_back (pos);
pre = pos;
vis [pos] = 1;
for (int j = 1; j <= c; j ++)
if (! vis [j] && low [j]> Map [pos] [j])
low [j] = Map [pos] [j];
}
}
int main ()
{
int a, b, d, k = 1;
ios :: sync_with_stdio (false);
while (cin >> c >> s >> q)
{
if (c + s + q == 0)
return 0;
ini ();
for (int i = 1; i <= s; i ++)
{
cin >> a >> b >> d;
Map [a] [b] = Map [b] [a] = d;
}
for (int i = 1; i <= q; i ++)
cin >> que [i] .a >> que [i] .b;
prim (c);
if (k! = 1)
cout << endl;
cout << "Case #" << k ++ << endl;
for (int i = 1; i <= q; i ++)
{
if (dp [que [i] .a] [que [i] .b] == maxint || dp [que [i] .a] [que [i] .b] ==-1)
cout << "no path" << endl;
else
cout << dp [que [i] .a] [que [i] .b] << endl;
}
}
return 0;
}
}
Ideas:
(said good ramble, in order to can not let oneself after two days forget)
First of all, since the requirement to walk from a to B must choose the least weight (note is not the right value of the and), then if there is A-c-b is 10 and 5 in addition there is a side is the A-d-b is 2 and 3, that obviously should go a-d-b, from this point of view, it is the minimum generation of the Rhythm of the tree (note For example, in the input sample Example 2), in addition to the requirements of any two node value can be considered floyed deformation.
Know is the smallest spanning tree, first choose an algorithm, there are prim and Kruskal optional, I usually use the Kruskal algorithm. In fact, this problem with Kruskal can do, and later see most of the code is used Kruskal plus floyed. But I suddenly thought of a higher algorithm with prim dynamic programming, similar to the RMQ kind, the specific idea is as follows.
First select the prim algorithm, the prim algorithm is randomly find a point as the starting point, and then find the node with the lowest weight of the edge.
1.Because the data given in the data is not necessarily fully connected, which requires us to the data in the graph into the smallest connected forest. For example 2 of the data, according to the idea of the prim algorithm, found the order of the nodes are 3, 6, 4, but the next time in the search for nodes because there is no and 12364 of the 5 nodes connected points, so go to 4 when the card is dead. Because of the adjacency matrix, the weights connected to each node are initially initialized to maxint values, which is equivalent to Maxint, so the min value (min in code) that is used to update the minimum edge is reserved for the last found value, such as the last time you found the value 4 to 5 is min= Maxint, because all sides of the weights are less than or equal to maxint (equal to maxint equivalent to not connected), so if the current value is maxint description of the current node found a non-connected point, do not go to the tube, update the next min for maxint+1 on the line.
As shown in figure
2.
Plug each found point into a vector and dynamically plan the weights between each update of the currently found node and the last node found (the last found node is definitely the edge of the smallest spanning tree found) to update all previous edges. The state transition equation is
First, Min is added to the interval first, dp[pos][pr.e]=dp[pr.e][pos]=min, indicating that the weights before the node pre and node pos are min.
And then using the transfer equation
Dp[pos][vp[i]]=dp[vp[i]][pos]=max (Dp[vp[i]][pre],dp[pos][pre])
All of the nodes that were previously found are saved in VP.
For example, found node 2-1-3-6 now found node 4, with weights between 4 and 6 to update the size of 4 to 3, 4 to 1, 4 to 2