HDU 1385 Minimum Transport Cost(dijkstra和floyd都可實現)


題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1385

題目大意:啊,寫題目大意好煩啊,不想寫了。哎,還是寫吧。這道題的意思就是給你所有城市到其他城市的道路成本和經過每個城市的城市稅,給你很多組城市,要求你找出每組城市間的最低運輸成本並且輸出路徑,如果有多條路徑則輸出字典序最小的  的那條路徑。注意,起點城市和終點城市不需要收城市稅。

這道題我是用dijkstra寫的,其實這種需要輸出字典序路徑的題目用floyd寫的話會簡單很多,不過用floyed寫的話就有很多東西學不到。我在這只講解如何用dijkstra實現。

代碼:

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 105
#define N 50
int path[maxn],mp[maxn][maxn],tax[maxn],vis[maxn],n,dis[maxn];
int len;  
void dfs(int k,char s[])  
{  
    if(k==-1) return ;  
    dfs(path[k],s);  
    s[len++]=k+'0';  
}  
int cmp(int re,int now)  
{  
    char s1[N],s2[N];
    len=0;  
    dfs(re,s1);//將起點到re的最短路徑儲存
    s1[len]=0;  
    len=0;  
    dfs(now,s2);//將起點到u的最短路徑儲存
    s2[len++]=re+'0';//連接re點
    s2[len]=0;  
    if(strcmp(s1,s2)>0)//比較兩條最短路徑字典序大小
        return 1;  
    return 0;  
} 
void djk(int st,int ed){
	int i,j,k;
	for(i=1;i<=n;i++){
		dis[i]=mp[st][i]+tax[i];//將邊權與點權相加,視為經過i號城市的代價
		if(i==st)
		continue;
	        if(dis[i]<inf)
                path[i]=st;
	}
	for(i=0;i<n-1;i++){
		int mi=inf,u;
		for(j=1;j<=n;j++){
			if(dis[j]<mi&&!vis[j]){
				mi=dis[j];
				u=j;
			}
		}
		vis[u]=1;
		for(k=1;k<=n;k++){
				if(mp[u][k]<inf){
					if(dis[k]>dis[u]+mp[u][k]+tax[k]){
					dis[k]=dis[u]+mp[u][k]+tax[k];
					path[k]=u;
					}
					else if(dis[k]==dis[u]+mp[u][k]+tax[k]&&cmp(k,u)){//若有多條最短路徑進行字典序大小判斷
						path[k]=u;//注意比較最短路徑大小不能之比較某一個點,要比較整條路徑
					}
			}
		}
	}
}
void show(int v,int st)
{
    if(v==st)
    {
        cout<<v;
        return ;
    }
    show(path[v],st);
    cout<<"-->"<<v;
}
int main()
{
	int i,j,k;
	while(cin>>n){
		for(i=1;i<=n;i++){
			for(j=1;j<=n;j++){
				cin>>mp[i][j];//輸入道路成本
			}
		}
		for(i=1;i<=n;i++){
			cin>>tax[i];//輸入每個城市的城市稅
		}
		for(i=1;i<=n;i++){
		for(j=1;j<=n;j++){
			if(mp[i][j]==-1)
			mp[i][j]=inf;//-1的話不好進行判斷,因此將其賦值為inf
		}
	}
		int x,y;
		while(cin>>x>>y&&(x!=-1||y!=-1)){
			memset(vis,0,sizeof(vis));
			memset(path,-1,sizeof(path));
			djk(x,y);
			cout<<"From "<<x<<" to "<<y<<" :"<<endl;
			cout<<"Path: ";
			show(y,x);
			cout<<endl;
			cout<<"Total cost : "<<dis[y]-tax[y]<<endl;//減去終點城市的城市稅
			cout<<endl;
		}
	}
}

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com