PAT甲級真題 1003 Emergency

一、題目
在這裏插入圖片描述
在這裏插入圖片描述
二、思路
在Dijkstra算法的基礎上,統計最短路徑條數和最大頂點權值(消防隊數目)。需判斷什麼時候出現相同最短路徑(D[j] == D[k] + dist[k][j]),出現後,tot數組該如何變化(tot[j]+=tot[k];)。最大消防隊比較容易。

三、代碼

int N,D[500],s[500],tot[500],team[500],num[500];
//N-城市數,D最短路徑數組,s標記數組,tot相同最短路徑數目,team每個城市擁有的消防隊數目,num召集的消防隊數目

void Dijkstra(int v,int dist[][500]) {
	int i, j, k, v1, min, max = 10000;
	v1 = v;
	for (i = 0; i < N; i++) {//初始化D、s、tot、num
		D[i] = dist[v1][i];
		s[i] = 0;
		if (D[i] == max) {//表明c1到該點沒有邊
			tot[i] = 0;
			num[i] = 0;
		}
		else {
			tot[i] = 1;
			num[i] = team[v1]+team[i];
		}
	}
	s[v1] = 1; num[v1] = team[v1];//對c1的單獨初始化
	for (i = 0; i < N - 1; i++) {
		min = max + 1;//保證所有頂點都能被訪問
		//尋找最短路徑
		for (j = 0; j < N; j++) {
			if ((s[j] == 0) && (D[j] < min)) {
				min = D[j]; k = j;
			}
		}
		s[k] = 1;
		//修改部分
		for (j = 0; j < N; j++) {
			if ((s[j] == 0) && (D[j] > D[k] + dist[k][j])) {
				D[j] = D[k] + dist[k][j];
				tot[j] = tot[k];
				num[j] = num[k] + team[j];//由於路徑改了,經過的頂點也就變了,這裏必須變
			}
			else if ((s[j] == 0) && (D[j] == D[k] + dist[k][j])) {//出現相同最短路徑
				tot[j]+=tot[k];
				if (num[j] < num[k] + team[j])//需要判斷下哪個引起的消防隊更多
					num[j] = num[k] + team[j];
			}
		}
	}
	return;
}

int main() {
	int M, c1, c2, i, j, dist[500][500] = { 0 }, ct1, ct2;//dist鄰接矩陣
	scanf("%d %d %d %d", &N, &M, &c1, &c2);
	for (i = 0; i < N; i++)
		scanf("%d", &team[i]);
	for (i = 0; i < M; i++) {
		scanf("%d %d", &ct1, &ct2);
		scanf("%d", &dist[ct1][ct2]);
		dist[ct2][ct1] = dist[ct1][ct2];
	}
	for (i = 0; i < N; i++)
		for (j = 0; j < N; j++)
			if ((i != j) && (dist[i][j] == 0))
				dist[i][j] = 10000;
	Dijkstra(c1, dist);
	printf("%d %d", tot[c2], num[c2]);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章