Test for Job--P3249

Test for Job

这道题开始考虑有负权,用贝尔曼福特,算出能获得的最大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[] adj = new LinkedList[n+1];
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 currentList = new 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);
}
}
}

posted @ 2021-04-30 16:51  Monstro  阅读(55)  评论(0)    收藏  举报