HDU-1874畅通工程续(最短路问题)

题意:本题是给你一个求最短路的问题,就是给你n个点以及一些点之间的距离,最后再让你输出两个点之间的最短路径,如果这个点不联通就输出-1
思路:非常经典的最短路问题,而且数据范围小自由200,所以直接就用最暴力的Floyd算法,或是Dijkstra算法(如果你不明白这个算法推荐你看下这个http://www.cnblogs.com/ahalei/p/3622328.html但本题一个大坑就是他并没有所两个点之间只有一条路,所以在读入是要先判断一下,把最段的那条路读入
代码如下:

#include<iostream>
#include<cstdio>
#include<cmath>
#define MAX 210
const int INF = 0xffffff;//0x表示十六进制,这里你可以自己定义一个比较大的数就行 
using namespace std;
int main(void)
{
    int n,m,e[MAX][MAX];
    int i,j,k;
    while(cin >> n >> m)
    {
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                if(i == j)
                    e[i][j] = 0;
                else
                    e[i][j] = INF;
            }
        }
        int a,b,c;
        for(i=0;i<m;i++)
        {
            cin >> a >> b >> c;
            if(e[a][b] > c)//题目并未说两个点之间只有一条道路,所以这里要加个if判断,保留最小距离的那个 
            {
                e[a][b] = c;
                e[b][a] = c;
            }
        }
        for(k=0;k<n;k++)
        {
            for(i=0;i<n;i++)
            {
                for(j=0;j<n;j++)
                {
                    if(e[i][j] > e[i][k] + e[k][j])
                        e[i][j] = e[i][k] + e[k][j]; 
                }
            }
        }
        int w,v;
        cin >> w >> v;
        if(e[w][v] == INF)
            cout << "-1" << endl;//endl是换行,相当于C++中的\n 
        else
            cout << e[w][v] << endl;
    }
    return 0;
}
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAX_V 210
#define MAX_E 1100
using namespace std;
const int INF = 999999999;
int e[MAX_V][MAX_V],dis[MAX_V];
bool used[MAX_V];
int V,E;
void Dijkstra(int a){
    fill(dis,dis+V,INF);
    fill(used,used+V,false);
    dis[a] = 0;
    while(true){
        int v = -1;
        for(int u=0;u<V;u++){
            if(!used[u] && (v == -1 || dis[u] < dis[v])) v = u;
        }
        if(v == -1) break;
            used[v] = true; 
        for(int u=0;u<V;u++){
            dis[u] = min(dis[u],dis[v] + e[v][u]);
        }
    }
}
void startup(){
    for(int i=0;i<V;i++){
            for(int j=0;j<V;j++)
                if(i == j)  e[i][j] = 0;
                else e[i][j] = INF;
        }
}
int main(void)
{
    while(~scanf("%d %d",&V,&E))
    {
        for(int i=0;i<V;i++){
            for(int j=0;j<V;j++)
                if(i == j)  e[i][j] = 0;
                else e[i][j] = INF;
        }
        int a,b,c;
        for(int i=0;i<E;i++){
            scanf("%d %d %d",&a,&b,&c);
            if(e[a][b] > c)
            {
                e[a][b] = c;
                e[b][a] = c;
            }
        }
        int begin,over;
        scanf("%d %d",&begin,&over);
        Dijkstra(begin);
        if(dis[over] == INF)
            printf("-1\n");
        else
            printf("%d\n",dis[over]);
    }
    return 0;
}

最后,其实我之间做这题,第一个想到的是一中类似于深搜(DFS)的算法,就是用一个数记录一下到该点的距离,最后再用一个min把最小的那个存下来,最后再输出,可是却超时了,代码如下,喜欢的可以看一下:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<limits.h>
const int INF = INT_MAX;
int n,m;
bool book[210];
int e[210][210];
int begin,over,min;
void dfs(int cur,int dis)//dis到达这点的距离 
{
    int i;
    if(dis > min)
        return;
    if(cur == over)
    {
        min = dis;
        return;
    }
    for(i=0;i<n;i++)
    {
        if(book[i] == 0 && e[cur][i] != INF)//这点可以走 
        {
            book[i] = 1;
            dfs(i,dis+e[cur][i]);
            book[i] = 0;
        }
    }
    return;
}
int main(void)
{
    int i,j;
    while(~scanf("%d %d",&n,&m))
    {
        memset(book,0,sizeof(book));
        min = INF;
        for(i=0;i<=n;i++)
        {
            for(j=0;j<=n;j++)
            {
                if(i == j)
                    e[i][j] = 0;
                else    
                    e[i][j] = INF;
            }
        }
        int a,b,c;
        for(i=0;i<m;i++)
        {
            scanf("%d %d %d",&a,&b,&c);
            if(e[a][b] > c)
            {
                e[a][b] = c;
                e[b][a] = c;
            }
        }
        scanf("%d %d",&begin,&over);//起点和终点 
        book[begin] = 1;
        dfs(begin,0);
        if(min == INF)
            printf("-1\n");
        else
            printf("%d\n",min);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值