poj 1797 Heavy Transportation

来源:互联网 发布:mac强制卸载 编辑:程序博客网 时间:2024/06/03 19:26

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

Heavy Transportation
Time Limit:3000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u
Submit Status

Description

Background 
Hugo Heavy is happy. After the breakdown of the Cargolifter project he can now expand business. But he needs a clever man who tells him whether there really is a way from the place his customer has build his giant steel crane to the place where it is needed on which all streets can carry the weight. 
Fortunately he already has a plan of the city with all streets and bridges and all the allowed weights.Unfortunately he has no idea how to find the the maximum weight capacity in order to tell his customer how heavy the crane may become. But you surely know. 

Problem 
You are given the plan of the city, described by the streets (with weight limits) between the crossings, which are numbered from 1 to n. Your task is to find the maximum weight that can be transported from crossing 1 (Hugo's place) to crossing n (the customer's place). You may assume that there is at least one path. All streets can be travelled in both directions.

Input

The first line contains the number of scenarios (city plans). For each city the number n of street crossings (1 <= n <= 1000) and number m of streets are given on the first line. The following m lines contain triples of integers specifying start and end crossing of the street and the maximum allowed weight, which is positive and not larger than 1000000. There will be at most one street between each pair of crossings.

Output

The output for every scenario begins with a line containing "Scenario #i:", where i is the number of the scenario starting at 1. Then print a single line containing the maximum allowed weight that Hugo can transport to the customer. Terminate the output for the scenario with a blank line.

Sample Input

13 31 2 31 3 42 3 5

Sample Output

Scenario #1:4

题意:Hugo Heavy要从城市1到城市N运送货物,有M条道路,每条道路都有它的最大载重量,问从城市1到城市N运送最多的重量是多少。

其实题意很简单,就是找一条1-->N的路径,在不超过每条路径的最大载重量的情况下,使得运送的货物最多。

分析:其实就是找一条带权路径,使得路径上最小的权值最大化,只要求一次最大生成树即可,本也没啥复杂的算法,不过这题的解题思路让我对最小生成树有了更深的理解,在这里我讲一下我对prim算法的理解。

prim算法

1。设有一集合S,首先,将起点s(最后就成了最小生成树的根节点)放入集合,则S = {s}

2。找到距离集合S最近的一点u,加入S集合

3。通过点u,更新其余未进入集合S的点到集合S的距离

4。如果集合S外没有点了,结束,否则转到步骤2

其实整个过程中就是在找到一个距离起点集合S路径最小的点,加入进来,然后不断更新,这就像在建一棵连通树,在保证连通的情况下,不断的加入新的叶子节点,由于每次加入的边权最小,所以最后建成的就是一棵最小生成树,它能保证起点到任意一点的路径上最小的权值最小化;同理,最大生成树就是在加点的时候找权值最大的加入就行了。

 

然后看这道题:找到一条1-->N的路径,就保证连通,最后要求最小权值最大化,就是要求路径中每条边权中的最小者最大,那么就可以用最大生成树的方法,不断地将最大权值的边加入,遇到终点N就结束,这样就不会再找到一条可以更换当前路径的更好的路径了。

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <cmath>#include <cstdlib>#include <limits>#include <queue>#include <stack>#include <vector>using namespace std;#define N 2100#define INF 0x3f3f3f3f#define PI acos (-1.0)#define EPS 1e-8int T, n, m, g[N][N], vis[N], dist[N];void Init ();void Prim (int sa);int main (){    cin >> T;    int flag = 1;    while (T--)    {        Init ();        cin >> n >> m;        int a, b, c;        for (int i=0; i<m; i++)        {            cin >> a >> b >> c;            g[a][b] = max (g[a][b], c);            g[b][a] = g[a][b];        }        cout << "Scenario #" << flag++ << ':' << endl;        Prim (1);    }    return 0;}void Prim (int sa){    for (int i=1; i<=n; i++)        dist[i] = g[sa][i];    dist[sa] = 0;    vis[sa] = 1;    int ans = INF;    for (int i=1; i<=n; i++)    {        int index = 0, minx = -INF;        for (int j=1; j<=n; j++)        {            if (minx < dist[j] && !vis[j])                minx = dist[j], index = j;        }        if (ans > minx) ans = minx;        if (index == n) break;        vis[index] = 1;        for (int j=1; j<=n; j++)        {            if (!vis[j] && dist[j] < g[index][j])                dist[j] = g[index][j];        }    }    cout << ans << endl << endl;}void Init (){    memset (vis, 0, sizeof (vis));    for (int i=1; i<=n; i++)    {        for (int j=1; j<=i; j++)            g[i][j] = g[j][i] = -INF;    }}

spfa

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <cmath>#include <cstdlib>#include <limits>#include <queue>#include <stack>#include <vector>#include <map>using namespace std;#define N 1010#define INF 0x3f3f3f3f#define PI acos (-1.0)#define EPS 1e-8#define met(a, b) memset (a, b, sizeof (a))int vis[N], n, m, dist[N], g[N][N];int spfa ();int main (){    int t, k = 1;    scanf ("%d", &t);    while (t--)    {        scanf ("%d %d", &n, &m);        for (int i=1; i<=n; i++)        for (int j=1; j<=n; j++)        if (i != j) g[i][j] = 0;        for (int i=1; i<=m; i++)        {            int a, b, c;            scanf ("%d %d %d", &a, &b, &c);            g[b][a] = g[a][b] =  max (g[a][b], c);        }        printf ("Scenario #%d:\n%d\n\n", k++, spfa ());    }    return 0;}int spfa (){    queue <int> que;    que.push (1);    for (int i=1; i<=n; i++)        dist[i] = 0;    dist[1] = INF;    met (vis, 0);    while (que.size ())    {        int temp = que.front (); que.pop ();        vis[temp] = 0;        for (int i=1; i<=n; i++)        {            if (dist[i] < min (dist[temp], g[temp][i]))            {                dist[i] = min (dist[temp], g[temp][i]);                if (!vis[i])                {                    vis[i] = 1;                    que.push (i);                }            }        }    }    return dist[n];}/*3 31 2 31 3 12 3 5*/


0 0
原创粉丝点击