HDU 1224 Free DIY Tour(最短路或DP)

题意:给你n个城市,每个城市都有一个风景值,再给你m条路,每条路连接两个城市,只能从序号小的到序号大的,

你从1号到n+1(就是1号)号能经过的风景值得和最大为多少,并且输出路径。


思路:很容易想到可以用求最短路的方法求一个最长路;因为满足只能从小序号的城市到大序号的城市,所以也可以用DP来做,从小的城市开始遍历更新。


(注意每个测试预处理的时候别忘了把n+1也清空)

最短路代码:

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Vector;

public class Main {
	static final int maxn = 105;
	static final int INF = 0x3f3f3f3f;
	static int[] dis = new int[maxn];
	static int[] cost = new int[maxn];
	static int[] pre = new int[maxn];
	static int[] rec = new int[maxn];
	static boolean[] book = new boolean[maxn];
	static Vector<Integer>[] g = new Vector[maxn];

	static void spfa() {
		Arrays.fill(pre, -1);
		Arrays.fill(dis, 0);
		Arrays.fill(book, false);
		Queue<Integer> q = new LinkedList<Integer>();
		q.clear();
		q.add(1);
		dis[1] = 0;
		while (!q.isEmpty()) {
			int u = q.poll();
			book[u] = false;
			for (int i = 0; i < g[u].size(); i++) {
				int v = g[u].get(i);
				if (dis[u] + cost[v] >= dis[v]) {
					dis[v] = dis[u] + cost[v];
					pre[v] = u;
					if (!book[v]) {
						book[v] = true;
						q.add(v);
					}
				}
			}
		}
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		for (int i = 0; i < maxn; i++)
			g[i] = new Vector<Integer>();
		int _, n, m, ca = 1;
		_ = sc.nextInt();
		while (_-- != 0) {
			for (int i = 0; i < maxn; i++) {
				g[i].clear();
				cost[i] = 0;
			}
			n = sc.nextInt();
			for (int i = 1; i <= n; i++)
				cost[i] = sc.nextInt();
			m = sc.nextInt();
			for (int i = 1; i <= m; i++) {
				int u = sc.nextInt();
				int v = sc.nextInt();
				if (u > v) {
					int t = u;
					u = v;
					v = t;
				}
				g[u].add(v);
			}
			spfa();
			System.out.println("CASE " + (ca++) + "#");
			System.out.println("points : " + dis[n + 1]);
			System.out.print("circuit : ");
			int cnt = 0;
			int p = n + 1;
			while (p != -1) {
				rec[cnt++] = p;
				p = pre[p];
			}
			for (int i = cnt - 1; i > 0; i--)
				System.out.print(rec[i] + "->");
			System.out.println("1");
			if (_ != 0)
				System.out.println();
		}
	}
}


DP代码:

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Vector;

public class Main {
	static final int maxn = 105;
	static final int INF = 0x3f3f3f3f;
	static int[] dp = new int[maxn];
	static int[] cost = new int[maxn];
	static int[] pre = new int[maxn];
	static int[] rec = new int[maxn];
	static Vector<Integer>[] g = new Vector[maxn];

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		for (int i = 0; i < maxn; i++)
			g[i] = new Vector<Integer>();
		int _, n, m, ca = 1;
		_ = sc.nextInt();
		while (_-- != 0) {
			for (int i = 0; i < maxn; i++) {
				g[i].clear();
				cost[i] = 0;
			}
			n = sc.nextInt();
			for (int i = 1; i <= n; i++)
				cost[i] = sc.nextInt();
			m = sc.nextInt();
			for (int i = 1; i <= m; i++) {
				int u = sc.nextInt();
				int v = sc.nextInt();
				if (u > v) {
					int t = u;
					u = v;
					v = t;
				}
				g[u].add(v);
			}
			Arrays.fill(dp, 0);
			Arrays.fill(pre, -1);
			for (int i = 1; i <= n; i++) {
				int u = i;
				for (int j = 0; j < g[i].size(); j++) {
					int v = g[i].get(j);
					if (dp[u] + cost[v] > dp[v]) {
						dp[v] = dp[u] + cost[v];
						pre[v] = u;
					}
				}
			}
			System.out.println("CASE " + (ca++) + "#");
			System.out.println("points : " + dp[n + 1]);
			System.out.print("circuit : ");
			int cnt = 0;
			int p = n + 1;
			while (p != -1) {
				rec[cnt++] = p;
				p = pre[p];
			}
			for (int i = cnt - 1; i > 0; i--)
				System.out.print(rec[i] + "->");
			System.out.println("1");
			if (_ != 0)
				System.out.println();
		}
	}
}


猜你喜欢

转载自blog.csdn.net/CillyB/article/details/80192170