1. 程式人生 > >無向圖最短路徑問題

無向圖最短路徑問題

 

給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。

Input

輸入n,m,點的編號是1~n,然後是m行,每行4個數 a,b,d,p,表示a和b之間有一條邊,且其長度為d,花費為p。最後一行是兩個數 s,t;起點s,終點。n和m為0時輸入結束。 
(1<n<=1000, 0<m<100000, s != t)

Output

輸出 一行有兩個數, 最短距離及其花費。

Sample Input

3 2
1 2 5 6
2 3 4 5
1 3
0 0

Sample Output

9 11

求最短路徑問題,即從一點到另外一點的最短路徑,Dijkstra演算法即可解決,時間複雜度O(n^2)

在最短路都多條的情況下,求最少花費,加個判斷條件即可

 

for(int i=1;i<=n;i++)
        {
    		if(dis[i]==dis[u]+g[u][i])
            {
        	    if(c[i]>c[u]+cost[u][i] )
        	        c[i]=c[u]+cost[u][i];
		    }
	        else if(dis[i]>dis[u]+g[u][i])  
		       {
			       dis[i]=dis[u]+g[u][i];
        	       c[i]=c[u]+cost[u][i];
		       }
    	   
       }

程式碼如下:

 

//Dijkstra演算法 臨接矩陣 
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1005;
int g[N][N];     //存圖 N->N 的距離 
int cost[N][N];  //存圖N->N 的花費 
int c[N];        //存最小花費 
int dis[N];      //存最小距離 
int vis[N],n,m;  //標記改點是否已經走過
int t1,t2; 
#define Inf 0x3f3f3f3f
void Init()
{
    memset(g,Inf,sizeof(g));
    memset(cost,Inf,sizeof(cost));
    for(int i=1;i<=n;i++)
    {
    	g[i][i]=0;
    	cost[i][i]=0;
	}
}
void  GetMap()
{
    for(int i=0;i<m;i++)
    {
        int u,v,w,p;
        scanf("%d%d%d%d",&u,&v,&w,&p);
      if(g[u][v]>w)
      {
        g[u][v]=g[v][u]=w;
        cost[u][v]=cost[v][u]=p;
      }
    }
}
void Dijkstra()
{
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)    
    {
    	dis[i]=g[t1][i];
    	c[i]=cost[t1][i];
	}
    vis[t1]=1;
    int u;
    for(int k=1;k<n;k++)
    {
      int minn=Inf;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]&&dis[i]<minn)
               {
                   minn=dis[i];
                   u=i;
               }  
        }
        vis[u]=1;
        for(int i=1;i<=n;i++)
        {
    		if(dis[i]==dis[u]+g[u][i])
            {
        	    if(c[i]>c[u]+cost[u][i] )
        	        c[i]=c[u]+cost[u][i];
		    }
	        else if(dis[i]>dis[u]+g[u][i])  
		       {
			       dis[i]=dis[u]+g[u][i];
        	       c[i]=c[u]+cost[u][i];
		       }
    	   
       }
    }
}
int main()
{
    while(scanf("%d%d",&n,&m))
    {
    	if(n==0 && m==0) break;
    	Init();
        GetMap(); 
        scanf("%d%d",&t1,&t2);
        Dijkstra();  
        cout<<dis[t2]-dis[t1]<<" "<<c[t2]-c[t1]<<endl;
	}
    return 0;
}