1. 程式人生 > >PAT 1003 Emergency

PAT 1003 Emergency

PAT 1003 emergency

學習djstra演算法

虛擬碼:

設d[0]=0, 其他d[i]=INF
迴圈n次{
	在所有為標號結點中選出d值最小結點x
	給結點x標記
	對於x出發的所有邊(x,y), 更新d[y]=min{d[y], d[x]+w(x,y)}
}

總結:

迴圈內主要分為兩部分

  1. 找出當前結點的最短的路徑
  2. 根據找出的最短路徑的結點, 來更新dist表: 若該結點相鄰的邊比原來小,則更新
#include <stdio.h>
#define INF 99999999
#define MAX 501
int src, tar;

void dijkstra(int
g[][MAX], int n,int team[MAX]){ int x, y, i, m; int dist[MAX]; int v[MAX]; int count[MAX]; int dt[MAX]; //src到當前路徑的最大隊伍數 for(i=0; i < n; i++){ v[i] = 0; dt[i] = team[src]; count[i] = 1; dist[i] = g[src][i]; if(dist[i] != INF && i !=
src){ //此處特別注意!!!(i=src)改了 30分鐘, 第二個案例過不了 dt[i] = team[i]+team[src]; } } count[src] = 1; v[src] = 1; for(i=0; i < n; i++){ m = INF; for(y=0; y < n; y++){ //得到權值最小的邊 if(!v[y] && dist[y] <= m){ m = dist[x=y]; }
} if(m == INF || x == tar) break; v[x] = 1; for(y=0; y < n; y++){ //更新dist if(dist[x]+g[x][y] < dist[y]){ dist[y] = dist[x]+g[x][y]; dt[y] = dt[x] + team[y]; count[y] = count[x]; }else if(dist[x]+g[x][y] == dist[y]){ if (dt[x] + team[y] > dt[y]) dt[y] = dt[x] + team[y]; count[y] += count[x]; } } } printf("%d %d",count[tar], dt[tar]); } int main(void){ int n, m; scanf("%d %d %d %d", &n, &m, &src, &tar); int i, j; int team[MAX]; int g[MAX][MAX]; for(i = 0;i < n; i++){ for(j = 0; j < n; j++){ g[i][j] = INF; } } g[src][src] = 0; for(i =0; i < n; i++){ scanf("%d", &team[i]); } int t,k,w; for(i = 0;i < m; i++){ scanf("%d %d %d", &t, &k, &w); g[t][k] = g[k][t] = w; } dijkstra(g, n, team); return 0; }

DFS 演算法

注意剪枝

import java.util.Arrays;
import java.util.Scanner;

public class Main{
	static int INF = 999999999;
	static boolean[] visited;
	static int path;
	static int team;
	static int len = INF;
	static int n;
	static int m;
	static int src, tar;
	static int[] city;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt(); // citiy_num
		m = sc.nextInt(); // rods_num
		src = sc.nextInt();
		tar = sc.nextInt();
		int i;
		city = new int[n];
		int[][] g = new int[n][n];
		for (i = 0; i < n; i++)
			Arrays.fill(g[i], INF);

		visited = new boolean[n];
		for (i = 0; i < n; i++) {
			city[i] = sc.nextInt();
			g[i][i] = 0;
			visited[i] = false;
		}

		for (i = 0; i < m; i++) {
			int r = sc.nextInt();
			int c = sc.nextInt();
			int w = sc.nextInt();
			g[r][c] = w;
			g[c][r] = w;
		}
		sc.close();
		
		visited[src] = true;
		Dfs(g, src, city[src], 0);
		System.out.printf("%d %d", path, team);
	}
	
	public static void Dfs(int[][] g,int cur, int teamCount,  int curLen){
		
		if(curLen > len){
			return ;
		}
		if(cur == tar){
			if(curLen < len){
				len = curLen;
				path = 1;
				team = teamCount;
			}else if (curLen == len){
				path ++;
				if(team < teamCount){
					team = teamCount;
				}
			}
			return ;
		}
		for(int i = 0; i < n; i++){
			if(!visited[i] && g[cur][i] != INF){
				
				visited[i] = true;
				Dfs(g, i, teamCount + city[i], curLen+g[cur][i]);
				visited[i] = false;
			}
		}
	}
	
}