zoukankan      html  css  js  c++  java
  • 畅通project续HDU杭电1874【dijkstra算法 || SPFA】

    http://acm.hdu.edu.cn/showproblem.php?pid=1874


    Problem Description
    某省自从实行了非常多年的畅通project计划后。最终修建了非常多路。只是路多了也不好,每次要从一个城镇到还有一个城镇时,都有很多种道路方案能够选择,而某些方案要比还有一些方案行走的距离要短非常多。这让行人非常困扰。



    如今,已知起点和终点,请你计算出要从起点到终点。最短须要行走多少距离。

     

    Input
    本题目包括多组数据。请处理到文件结束。
    每组数据第一行包括两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
    接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。


    再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。

     

    Output
    对于每组数据,请在一行里输出最短须要行走的距离。

    假设不存在从S到T的路线,就输出-1.

     

    Sample Input
    3 3 0 1 1 0 2 3 1 2 1 0 2 3 1 0 1 1 1 2
     

    Sample Output
    2 -1
     

    //dijkstra算法

    #include<stdio.h>
    #include<string.h>
    #define INF 0x3f3f3f3f
    int map[220][220];
    int dis[1100];
    bool used[1100];
    int n;
    int i,j;
    void dijkstra(int u)
    {
    	memset(used,0,sizeof(used));
    	memset(dis,INF,sizeof(dis));
    	int pos=u;
    	for(i=0;i<n;++i)//第一次给dis赋值 
    	{
    		dis[i]=map[u][i];
    	}
    	dis[u]=0;
    	used[u]=1;
    	for(i=1;i<n;++i)//再找n-1个点 
    	{
    		int min=INF;
    		for(j=0;j<n;++j)
    		{
    			if(!used[j]&&dis[j]<min)
    			{
    				min=dis[j];
    				pos=j;
    			}
    		} 
    		used[pos]=1;
    		dis[pos]=min;
    		for(j=0;j<n;++j)//把dis数组更新,也叫松弛
    		{
    			if(!used[j]&&dis[j]>map[pos][j]+dis[pos])
    			{
    				dis[j]=map[pos][j]+dis[pos];
    			}
    		}
    	}
    
    }
    int main()
    {
    	int m;
    	int u,v,w;
    	int s,e;
    	while(~scanf("%d%d",&n,&m))
    	{		
    		for(i=0;i<n;i++)
          		for(j=0;j<n;j++)
            		map[i][j]=INF;
    		while(m--)
    		{
    			scanf("%d%d%d",&u,&v,&w);
    			if(map[u][v]>w)
    				map[u][v]=map[v][u]=w;
    		}
    		scanf("%d%d",&s,&e);
    		if(s==e) 
    		{
    			printf("0
    ");
    			continue;
    		}
    		dijkstra(s);
    		if(dis[e]==INF) 
    			printf("-1
    ");
    		else printf("%d
    ",dis[e]);
    	}
    	return 0;
    }

    //SPFA

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #define MAXM 1100
    #define MAXN 220
    #define INF 0x3f3f3f3f
    using namespace std;
    struct Edge
    {
    	int from, to, val;
    	int next;
    }edge[MAXM];
    int head[MAXM];
    int dis[MAXN];
    int vis[MAXN];
    //int used[MAXM];
    int N, M;
    int edgenum;
    int s, e;
    void Add_Edge(int u, int v, int w)
    {
    	Edge E={u, v, w, head[u]};
    	edge[edgenum] = E;
    	head[u] = edgenum++;
    }
    bool SPFA()
    {
    	queue<int> q;
    	memset(dis, INF, sizeof(dis));
    	memset(vis, 0, sizeof(vis));
    //	memset(used, 0, sizeof(used));
    	vis[s]=1;
    	dis[s]=0;
    //	used[s]++;
    	q.push(s);
    	while(!q.empty())
    	{
    		int u=q.front();
    		q.pop();
    		vis[u]=0;
    		for(int i=head[u]; i!=-1; i=edge[i].next)//遍历于u相连的全部点 
    		{
    			int v=edge[i].to;
    			if(dis[v] > dis[u] + edge[i].val)
    			{
    				dis[v] = dis[u] + edge[i].val;
    				if(!vis[v])
    				{
    					vis[v]=1;
    					q.push(v);
    //					used[v]++;
    //					if(used[v]>N)//推断是否存在负环 
    //					{
    //						return 0;
    //					}
    				}
    			}
    		}
    	}
    	if(dis[e]==INF) printf("-1
    "); 
    	else printf("%d
    ",dis[e]);
    //	return 1;
    }
    int main()
    {
    	int u,v,w;
    	while(~scanf("%d%d", &N, &M))
    	{
    		memset(head, -1, sizeof(head));
    		edgenum=0;
    		while(M--)
    		{
    			scanf("%d%d%d", &u, &v, &w);
    			Add_Edge(u, v, w);
    			Add_Edge(v,u,w);//无向边 
    		}
    		scanf("%d%d",&s,&e);
    		SPFA();
    //		if(!SPFA()) printf("-1
    ");
    	}
    }



  • 相关阅读:
    LOJ#551 Matrix
    洛谷P5163 WD与地图
    洛谷P4831 Scarlet loves WenHuaKe
    LOJ#6118 鬼牌
    支配树
    线性插值
    PropertiesConfiguration
    ThreadLocal
    Thread
    FastJson
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/6926092.html
Copyright © 2011-2022 走看看