C Dijkstra + poids du nœud + poids du bord + numéro de bord statistique + numéro de chemin le plus court statistique + chemin enregistré 1087 Tous les chemins mènent à Rome (30 points)

1087 Tous les chemins mènent à Rome (30 分)

En effet, il existe de nombreuses routes touristiques différentes de notre ville à Rome. Vous êtes censé trouver à vos clients l'itinéraire le moins cher tout en gagnant le plus de bonheur.

Spécification d'entrée:
Chaque fichier d'entrée contient un cas de test. Pour chaque cas, la première ligne contient 2 entiers positifs N (2≤N≤200), le nombre de villes et K, le nombre total de routes entre des paires de villes; suivi du nom de la ville de départ. Les N-1 lignes suivantes donnent chacune le nom d'une ville et un entier qui représente le bonheur que l'on peut gagner de cette ville, à l'exception de la ville de départ. Puis K lignes suivent, chacune décrit un itinéraire entre deux villes au format City1 City2 Cost. Ici, le nom d'une ville est une chaîne de 3 lettres majuscules en anglais, et la destination est toujours ROM qui représente Rome.

Spécification de sortie:
Pour chaque cas de test, nous sommes censés trouver la route avec le moindre coût. Si un tel itinéraire n'est pas unique, celui avec le maximum de bonheur sera recommandé. Si un tel itinéraire n'est toujours pas unique, alors nous produisons celui avec le bonheur moyen maximum - il est garanti par le juge qu'une telle solution existe et est unique.

Par conséquent, dans la première ligne de sortie, vous devez imprimer 4 nombres: le nombre d'itinéraires différents avec le moindre coût, le coût, le bonheur et le bonheur moyen (ne prenez que la partie entière) de l'itinéraire recommandé. Ensuite, dans la ligne suivante, vous êtes censé imprimer l'itinéraire au format City1-> City2->… -> ROM.

Exemple d'entrée:

6 7 HZH
ROM 100
PKN 40
GDN 55
PRS 95
BLN 80
ROM GDN 1
BLN ROM 1
HZH PKN 1
PRS ROM 2
BLN HZH 2
PKN GDN 1
HZH PRS 1

Exemple de sortie:

3 3 195 97
HZH->PRS->ROM

Titre
Poids des nœuds: bonheur de chaque ville
Poids des
bords : coût de chaque chemin Compter les arêtes: compter le nombre de nœuds passés par le
chemin le plus court Chemins les plus courts: compter le nombre de chemins les plus courts
enregistrés Chemins enregistrés: enregistrés Chemin, sortie suivante

Chacun des éléments ci-dessus doit maintenir une liste;

int D[MAXcity];        //最少花费
int mostHap[MAXcity];  //最多快乐度
int Count[MAXcity];   //最短路径的个数 
int C[MAXcity];      //统计路程经过的边数 
int path[MAXcity];    //记录路径

Au moins les plus courts sont initialisés à INFINITY, le
nombre de côtés statistiques est initialisé à 0;

Développez l'algorithme de Dijkstra:

void Dijkstra()
{
	bool visited[MAXcity];
	fill(D,D+MAXcity,INFINITY); //最短距离 
	fill(visited,visited+MAXcity,false);
	fill(mostHap,mostHap+MAXcity,0);
	fill(Count,Count+MAXcity,0);
	fill(C,C+MAXcity,0);
	
	D[0]=0;     //自己到自己花钱0
	Count[0]=1; //自己到自己有一条 
	path[0]=-1; //设置开头-1,方便后续入遍历输出
	//
	while(1)
	{	
		int Min=INFINITY;
		int V=-1;
		for(int i=0;i<N;i++)
			if(!visited[i]&&D[i]<Min)
			{
				Min=D[i];
				V=i;
			}
	 
	 if(V==-1) break;
	 visited[V]=true;
	 for(int i=0;i<N;i++)
	 {
	 	if(!visited[i]){
		
	 	if(D[V]+Graph[V][i]<D[i])
	 	{
	 		D[i]=D[V]+Graph[V][i];
	 		mostHap[i]=mostHap[V]+happiness[i];
	 		Count[i]=Count[V]; 
	 		C[i]=C[V]+1;
	 		path[i]=V;
		 }
		 else if(D[V]+Graph[V][i]==D[i]){       
		 //这里的else很关键——小于后D[i]改变,可能满足后序的== 
		 	Count[i]+=Count[V];
		 	if(mostHap[i]<mostHap[V]+happiness[i])
		 	{
		 		D[i]=D[V]+Graph[V][i];
	 			mostHap[i]=mostHap[V]+happiness[i];
	 			path[i]=V;
	 			C[i]=C[V]+1;
			 } 
		 }
	 }
	 } 
	}
}

Notez que
si le jugement est égal, vous devez ajouter autre si:
parce que la condition précédente inférieure modifiera la valeur de D [i], vous pouvez entrer à nouveau == jugement;
difficile
de maintenir chaque liste;

要求数最短路径有多少条
 count[origin] = 1;
 如果找到更短路:count[i]=count[V];因为W与V只差一条边,所以两者相同;
 如果找到等长路:count[i]+=count[V];登场路的数量为W前面一个点的路的数量;

要求边数最少的最短路
 C[origin] = 0;
 如果找到更短路:C[i]=C[V]+1;
 如果找到等长路:C[i]=C[V]+1;

要求最短路径的快乐度最高
 mostHap[orrgin]=0;
 如果找到更短路:mostHap[i]=mostHap[V]+happiness[i]
 如果找到等长路:if(mostHap[V]+happiness[i]>mostHap[i])
mostHap[i]=mostHap[V]+happiness[i];

得到路径
 每个条件都加上 path[i]=V;
最后通过path[]可以一路找到出发点;

Méthode de saisie:
utilisez la carte, ouvrez le tableau des noms pour enregistrer le nom;
ouvrez le tableau du bonheur pour enregistrer le bonheur de chaque ville;

void input()
{
	cin>>N>>K>>names[0];       //名称 
	happiness[0]=0;            //幸福感 
	for(int i =1;i<N;i++)
	{
		cin>>names[i]>>happiness[i];
		if(names[i]=="ROM") Rom=i;
	}
	for(int i=0;i<K;i++)
	{
		string a,b;
		int x,y,cost;
		cin>>a>>b>>cost;
		x=Findname(names,a);
		y=Findname(names,b);
		Graph[x][y]=cost;
		Graph[y][x]=cost;
	}
}

La fonction findname utilisée est un simple numéro de séquence de recherche; l'
utilisation d'une carte de table de hachage peut être plus pratique à réaliser, mais je n'ai aucune utilité;

int Findname(string names[],string name)
{
	for(int i=0;i<N;i++)
	{
		if(names[i]==name)
			return i;
	}
}

Fichier d'en-tête et fonction principale

#include<iostream>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;
#define INFINITY 65533
#define MAXcity 201

string names[MAXcity];
int happiness[MAXcity];
int Graph[MAXcity][MAXcity];       //记得初始化为正无穷 
int N,K;
string start;
int Rom;

int main()
{
	fill(Graph[0],Graph[0]+MAXcity*MAXcity,INFINITY);
	input();
	//得到图,名称,幸福感列表;
	//求0到各点的最少钱,并加上幸福感 
	//若最少钱相等,选幸福感最大的路线
	//若还相等——平均幸福感最大的——即幸福感除以路过的城市数 
	Dijkstra();
	cout<<Count[Rom]<<" "<<D[Rom]<<" "<<mostHap[Rom]<<" "<<mostHap[Rom]/C[Rom]<<endl;
	stack<int> P;
	int i=Rom;
	P.push(i);
	while(path[i]!=-1)
	{
		i=path[i];
		P.push(i);
	}
	
	while(!P.empty())
	{
		int t=P.top();
		P.pop();
		if(t!=Rom)
		cout<<names[t]<<"->";
		else cout<<names[t];
	}
}
Publié 105 articles originaux · a gagné les éloges 6 · vues 4956

Je suppose que tu aimes

Origine blog.csdn.net/BLUEsang/article/details/105468051
conseillé
Classement