Test for Job--P3249
这道题开始考虑有负权,用贝尔曼福特,算出能获得的最大money就可以了,不过提交后wrong....
想了半天才发现,是从起点到终点,能够得到的最多money,而不是到某个点能得到的最大money....
所以拓扑排序一下,再进行计算就可以了.
拓扑排序之前,初始化点,需要加入一个所有起始点的父节点,和所有最终节点的子节点,构成一个图.
然后每次更新当前点得到的钱数.
不知道哪里错了的代码..... :nu:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int[] profit = new int[n+2];
for(int i = 1;i<=n;i++){
st = new StringTokenizer(br.readLine());
profit[i] = Integer.parseInt(st.nextToken());
}
Map<Integer,Integer> pointInDegrees = new HashMap<Integer,Integer>();
Edge[] edges = new Edge[n+2];
int start;
int end;
for(int i = 0;i<m;i++){
st = new StringTokenizer(br.readLine());
start = Integer.parseInt(st.nextToken());
end = Integer.parseInt(st.nextToken());
if(!pointInDegrees.containsKey(end)){
pointInDegrees.put(end,0);
}
pointInDegrees.put(end,pointInDegrees.get(end)+1);
if(edges[start] == null){
edges[start] = new Edge(start,0);
}
edges[start].nextPoints.add(end);
}
for(int i = 0;i<=n+1;i++){
if(edges[i] == null){
edges[i] = new Edge(i,0);
}
if(pointInDegrees.containsKey(i)){
edges[i].inDegress = pointInDegrees.get(i);
}
}
LinkedList<Edge> listAllPoint = new LinkedList<Edge>();
Edge startEdge = new Edge(0,0);
Edge endEdge = new Edge(n+1,0);
for(int i = 1;i<=n;i++){
listAllPoint.add(edges[i]);
if(edges[i].inDegress == 0){
startEdge.nextPoints.add(edges[i].point);
edges[i].inDegress++;
}
if(edges[i].nextPoints.size() == 0){
edges[i].nextPoints.add(endEdge.point);
endEdge.inDegress++;
}
}
listAllPoint.add(startEdge);
listAllPoint.add(endEdge);
Collections.sort(listAllPoint);
Edge pollEdge;
List<Integer> resultTopo = new LinkedList<Integer>();
long[] money = new long[n+2];
Arrays.fill(money,-10000000000L);
money[0] = 0;
while(!listAllPoint.isEmpty()){
pollEdge = listAllPoint.poll();
resultTopo.add(pollEdge.point);
for(int i=0;i<pollEdge.nextPoints.size();i++){
edges[pollEdge.nextPoints.get(i)].inDegress--;
if(money[pollEdge.nextPoints.get(i)] < money[pollEdge.point]+profit[pollEdge.nextPoints.get(i)]){
money[pollEdge.nextPoints.get(i)] = money[pollEdge.point]+profit[pollEdge.nextPoints.get(i)];
}
}
Collections.sort(listAllPoint);
}
System.out.println(money[n+1]);
}
static class Edge implements Comparable<Edge>{
int point;
LinkedList<Integer> nextPoints;
int inDegress;
public Edge(int point, int inDegress) {
this.point = point;
this.nextPoints = new LinkedList<Integer>();
this.inDegress = inDegress;
}
@Override
public int compareTo(Edge edge) {
return this.inDegress-edge.inDegress;
}
}
}
经过同事的帮助(这个是他的博客),时隔多日,我用数组存储入度出度,然后就Accept了 :taikaixin:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while (br.ready()){
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int[] profile = new int[n+1];
for(int i = 1;i<=n;i++){
st = new StringTokenizer(br.readLine());
profile[i] = Integer.parseInt(st.nextToken());
}
int[] inDegrees = new int[n+1];
int[] outDegrees = new int[n+1];
LinkedList
for(int i = 1;i<adj.length;i++){
adj[i] = new LinkedList
}
int from,to;
for(int i = 1;i<=m;i++){
st = new StringTokenizer(br.readLine());
from = Integer.parseInt(st.nextToken());
to = Integer.parseInt(st.nextToken());
adj[from].add(to);
inDegrees[to]++;
outDegrees[from]++;
}
long[] result = new long[n+1];
Arrays.fill(result,Integer.MIN_VALUE);
ArrayDeque
for(int i = 1;i<inDegrees.length;i++){
if(inDegrees[i] == 0){
currentList.addFirst(i);
result[i] = profile[i];
}
}
int current;
while (!currentList.isEmpty()){
current = currentList.pollLast();
for(Integer next:adj[current]){
inDegrees[next]--;
if(result[next]<result[current]+profile[next]){
result[next] = result[current]+profile[next];
}
if(inDegrees[next] == 0){
currentList.addFirst(next);
}
}
}
long ans = Integer.MIN_VALUE;
for(int i = 1;i<outDegrees.length;i++){
if(outDegrees[i] == 0){
ans = Math.max(result[i],ans);
}
}
System.out.println(ans);
}
}
}

浙公网安备 33010602011771号