程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDOJ/HDU---1874 暢通工程續 最短路(dijkstra)

HDOJ/HDU---1874 暢通工程續 最短路(dijkstra)

編輯:C++入門知識

這個題有一個小小的tricky,就是要考慮重邊的情況,如果遇到重復的邊,則直接取最小的邊。

Dijkstra(迪傑斯特拉)算法是典型的最短路徑路由算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴展,直到擴展到終點為止。Dijkstra算法能得出最短路徑的最優解,但由於它遍歷計算的節點很多,所以效率低。其基本思想是,設置頂點集合S並不斷地作貪心選擇來擴充這個集合。一個頂點屬於集合S當且僅當從源到該頂點的最短路徑長度已知。


初始時,S中僅含有源。設u是G的某一個頂點,把從源到u且中間只經過S中頂點的路稱為從源到u的特殊路徑,並用數組dist記錄當前每個頂點所對應的最短特殊路徑長度。Dijkstra算法每次從V-S中取出具有最短特殊路長度的頂點u,將u添加到S中,同時對數組dist作必要的修改。一旦S包含了所有V中頂點,dist就記錄了從源到所有其它頂點之間的最短路徑長度。

 

#include<iostream>   
using namespace std;  
const int maxn=205;  
const int intmax=99999;  
int weight[maxn][maxn];  //保存權值的鄰接矩陣    
int dis[maxn];  
int s,t;  
void dijkstra()  
{  
    bool Sset[maxn];       
    memset(Sset,0,sizeof(Sset));  
    Sset[s]=1;  
    for(int i=0;i<maxn;i++)  
    {  
        int u,v;  
        int tmp=intmax;  
        for(int i=0;i<maxn;i++)  
        {  
            if(!Sset[i]&&dis[i]<tmp)  
            {  
                u=i;  
                tmp=dis[i];   
            }  
        }  
        Sset[u]=1;  
        for(int i=0;i<maxn;i++)  
        {  
            if(!Sset[i]&&weight[u][i]<intmax)  
            {  
                int newdis=dis[u]+weight[u][i];  
                if(newdis<dis[i])dis[i]=newdis;  
            }  
        }  
    }  
}  
int main()  
{  
    int n,m;  
    while(cin>>n>>m)  
    {  
        int a,b,x;  
        for(int i=0;i<maxn;i++)  
            for(int j=0;j<maxn;j++)  
                weight[i][j]=intmax;  
        for(int i=0;i<m;i++)  
        {  
            cin>>a>>b>>x;  
            if(x<weight[a][b])  //處理重邊    
                weight[a][b]=weight[b][a]=x;  
        }  
        cin>>s>>t;  
        for(int i=0;i<maxn;i++)dis[i]=weight[s][i];  
        dis[s]=0;  //如果是起點到起點,則應該是0    
        dijkstra();  
        if(dis[t]<intmax)  
            cout<<dis[t]<<endl;  
        else cout<<-1<<endl;    //不存的情況應該是:權值無窮大    
    }  
    return 0;  
}  

#include<iostream>
using namespace std;
const int maxn=205;
const int intmax=99999;
int weight[maxn][maxn];  //保存權值的鄰接矩陣 
int dis[maxn];
int s,t;
void dijkstra()
{
	bool Sset[maxn];     
	memset(Sset,0,sizeof(Sset));
	Sset[s]=1;
	for(int i=0;i<maxn;i++)
	{
		int u,v;
		int tmp=intmax;
		for(int i=0;i<maxn;i++)
		{
			if(!Sset[i]&&dis[i]<tmp)
			{
				u=i;
				tmp=dis[i];	
			}
		}
		Sset[u]=1;
		for(int i=0;i<maxn;i++)
		{
			if(!Sset[i]&&weight[u][i]<intmax)
			{
				int newdis=dis[u]+weight[u][i];
				if(newdis<dis[i])dis[i]=newdis;
			}
		}
	}
}
int main()
{
	int n,m;
	while(cin>>n>>m)
	{
		int a,b,x;
		for(int i=0;i<maxn;i++)
			for(int j=0;j<maxn;j++)
				weight[i][j]=intmax;
		for(int i=0;i<m;i++)
		{
			cin>>a>>b>>x;
			if(x<weight[a][b])  //處理重邊 
				weight[a][b]=weight[b][a]=x;
		}
		cin>>s>>t;
		for(int i=0;i<maxn;i++)dis[i]=weight[s][i];
		dis[s]=0;  //如果是起點到起點,則應該是0 
		dijkstra();
		if(dis[t]<intmax)
			cout<<dis[t]<<endl;
		else cout<<-1<<endl;	//不存的情況應該是:權值無窮大 
	}
	return 0;
}


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved