hdu 2363(枚举+最短路好题)

Cycling

Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1247    Accepted Submission(s): 411

Problem Description

You
want to cycle to a programming contest. The shortest route to the
contest might be over the tops of some mountains and through some
valleys. From past experience you know that you perform badly in
programming contests after experiencing large differences in altitude.
Therefore you decide to take the route that minimizes the altitude
difference, where the altitude difference of a route is the difference
between the maximum and the minimum height on the route. Your job is to
write a program that finds this route.
You are given:

the number of crossings and their altitudes, and

the roads by which these crossings are connected.
Your
program must find the route that minimizes the altitude difference
between the highest and the lowest point on the route. If there are
multiple possibilities, choose the shortest one.
For example:

In
this case the shortest path from 1 to 7 would be through 2, 3 and 4,
but the altitude difference of that path is 8. So, you prefer to go
through 5, 6 and 4 for an altitude difference of 2. (Note that going
from 6 directly to 7 directly would have the same difference in
altitude, but the path would be longer!)

Input

On the first line an integer t (1 <= t <= 100): the number of test cases. Then for each test case:

One
line with two integers n (1 <= n <= 100) and m (0 <= m <=
5000): the number of crossings and the number of roads. The crossings
are numbered 1..n.

n lines with one integer hi (0 <= hi <= 1 000 000 000): the altitude of the i-th crossing.

m lines with three integers aj , bj (1 <= aj , bj <= n) and cj (1 <= cj <= 1 000 000): this indicates that there is a two-way road between crossings aj and bj of length cj . You may assume that the altitude on a road between two crossings changes linearly.
You
start at crossing 1 and the contest is at crossing n. It is guaranteed
that it is possible to reach the programming contest from your home.

Output

For each testcase, output one line with two integers separated by a single space:

the minimum altitude difference, and

the length of shortest path with this altitude difference.

Sample Input

1
7 9
4
9
1
3
3
5
4
1 2 1
2 3 1
3 4 1
4 7 1
1 5 4
5 6 4
6 7 4
5 3 2
6 4 2

Sample Output

2 11

题意:有n个点m条边,每个点都有一个高度,问在保证高度之差最小的情况下从1点到第n点,最小高度差和最短路分别是多少?

题解:这题做的时候完全没思路,一直在想两点之间的高度问题,怎样才能从子问题递推到父亲问题找到最优的解,后面还是不会,,,然后看了题解发现自己的思维太死板了。。这个题只要枚举所有的高度差,然后按照高度差排序,当在某个高度差的限制下我们能够达到第n点(当然这个时候路径上每个点都应该在low和high之间),那么这个结果就是我们要的结果。

#include <stdio.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <queue>
#include <string.h>
using namespace std;
typedef long long ll;
const int N = 105;
const int INF = 999999999;
struct Node { ///枚举高度差所需要用到的结构体
    int low,high;
}node[N*N];
struct Edge{
    int v,w,next;
}edge[N*N];
int head[N];
ll h[N];
int graph[N][N];
int n,m;
int cmp(Node a,Node b){
    return (a.high-a.low)<(b.high-b.low);
}
bool vis[N];
int d[N];
void addEdge(int u,int v,int w,int &k){
    edge[k].v = v,edge[k].w = w;
    edge[k].next = head[u],head[u]=k++;
}
void spfa(int s,int low,int high){
    queue<int > q;
    for(int i=1;i<=n;i++){
        d[i] = INF;
        vis[i] = false;
    }
    d[s] = 0;
    q.push(s);
    while(!q.empty()){
        int u = q.front();
        q.pop();
        vis[u] = false;
        if(h[u]>high||h[u]<low) continue;
        for(int k = head[u];k!=-1;k=edge[k].next){
            int v = edge[k].v,w = edge[k].w;
            if(h[v]>high||h[v]<low) continue;
            if(d[v]>d[u]+w){
                d[v] = d[u]+w;
                if(!vis[v]){
                    vis[v]=true;
                    q.push(v);
                }
            }
        }
    }
}
int main()
{
    int tcase;
    scanf("%d",&tcase);
    while(tcase--){
        memset(head,-1,sizeof(head));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%lld",&h[i]);
        }
        int tot = 0;
        for(int i=1;i<=m;i++){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            addEdge(a,b,c,tot);
            addEdge(b,a,c,tot);
        }
        int k = 0;
        for(int i=1;i<=n;i++){
            for(int j=i;j<=n;j++){
                if(h[i]<h[j]){
                    node[k].low = h[i];

                    node[k++].high = h[j];
                }
                else {
                    node[k].low = h[j];
                    node[k++].high = h[i];
                }
            }
        }
        sort(node,node+k,cmp);
        for(int i=0;i<k;i++){
            spfa(1,node[i].low,node[i].high);
            if(d[n]<INF){
                printf("%d %d\n",node[i].high-node[i].low,d[n]);
                break;
            }
        }
    }
}
时间: 2024-07-29 10:01:58

hdu 2363(枚举+最短路好题)的相关文章

HDU 5521.Meeting 最短路模板题

Meeting Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 3361    Accepted Submission(s): 1073 Problem Description Bessie and her friend Elsie decide to have a meeting. However, after Farmer Jo

hdu 2363

枚举加最短路 #include <stdio.h> #include <string.h> #include <algorithm> #include <queue> using namespace std; #define N 105 #define INF 0x7f7f7f7f struct Height{ int low,high,dif; }H[N*N]; struct Edge{ int u ,val,next; }e[N*N]; int h[N]

HDU 2544:最短路( 最短路径入门 &amp;&amp;Dijkstra &amp;&amp; floyd )

最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 30972    Accepted Submission(s): 13345 Problem Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找

最短路入门题

http://acm.hdu.edu.cn/showproblem.php?pid=2544 DJ #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #define N 1000001 using namespace std; int map[101][101]; int n,m; int v[101],

hdu 4587 2013南京邀请赛B题/ / 求割点后连通分量数变形。

题意:求一个无向图的,去掉两个不同的点后最多有几个连通分量. 思路:枚举每个点,假设去掉该点,然后对图求割点后连通分量数,更新最大的即可.算法相对简单,但是注意几个细节: 1:原图可能不连通. 2:有的连通分量只有一个点,当舍去该点时候,连通分量-1: 复习求割点的好题! #include<iostream> #include<cstdio> #include<vector> using namespace std; int n,m; vector<vector&

hdu oj 2544 最短路(最短路径)

最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 31874    Accepted Submission(s): 13798 Problem Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找

hdu 1999 不可摸数 水题。

不可摸数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7966    Accepted Submission(s): 2024 Problem Description s(n)是正整数n的真因子之和,即小于n且整除n的因子和.例如s(12)=1+2+3+4+6=16.如果任何数m,s(m)都不等于n,则称n为不可摸数. Input 包

poj1511/zoj2008 Invitation Cards(最短路模板题)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Invitation Cards Time Limit: 5 Seconds      Memory Limit: 65536 KB In the age of television, not many people attend theater performances. Antique Comedians of Malidinesia are aware of this fa

HDU 4085 斯坦纳树模板题

Dig The Wells Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 971    Accepted Submission(s): 416 Problem Description You may all know the famous story "Three monks". Recently they find som