POJ 3249 - Test for Job - Topological Order
Test for Job
描述
Dog先生被他的公司解雇了。为了养家糊口,他必须尽快找到一份新工作。如今,由于失业人数不断增加,很难找到工作。因此,一些公司在招聘时经常使用难度较大的测试。
测试是这样的:从一个城市出发,你可以通过一些有方向的道路到达另一个城市。每次你到达一个城市,你可以赚取一些利润或支付一些费用,让这个过程继续下去,直到你到达一个目标城市。
老板会计算你旅行的花费和你刚得到的利润。最后,他会决定你是否能被录用。
为了得到这份工作,Dog先生设法了解了他可能到达的所有城市的净利润Vi(负Vi表示钱是花的而不是赚的)以及城市之间的联系。
没有道路通向的城市为源城市,无通向其他城市道路的城市为目标城市。Dog先生的使命是从一个源头城市出发,选择一条通往目标城市的路线,通过这条路线他可以获得最大的利润。
Input
输入文件包括几个测试用例。
每个测试用例的第一行包含2个整数n和m(1 ≤ n ≤ 100000, 0 ≤ m ≤ 1000000)表示城市和道路的数量。
接下来的n行各包含一个整数。第i行描述了城市i的净利润Vi (0 ≤ |Vi| ≤ 20000)
接下来的m行各包含两个整数x,y,表示有一条从城市x到城市y的道路。
保证每一条路只出现一次,没有办法回到以前的城市。
Output
输出文件为每个测试用例包含一行,其中包含一个整数,表示Dog先生能够获得的最大利润(或花费的最小开支)
Sample Input
6 5
1
2
2
3
3
4
1 2
1 3
2 4
3 4
5 6
Sample Output
7
解决方案:有向图,起点入度为0,且需要排序,故使用拓扑排序
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
/**
** 解决方案:有向图,起点入度为0,且需要排序,故使用拓扑排序
*
* @author XA-GDD
*
*/
public class F_TestForJob {
static int N,M;
static TopologicalNode [] nodeArr=new TopologicalNode[100002];
static long ANS;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str;
StringTokenizer st;
while((str = br.readLine()) != null) {
if("".equals(str)) break;
st = new StringTokenizer(str);
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
//读取数据
for(int i=1;i<=N;i++) {
st = new StringTokenizer(br.readLine());
nodeArr[i] = new TopologicalNode(i,Integer.parseInt(st.nextToken()));
}
for(int i=1;i<=M;i++) {
st = new StringTokenizer(br.readLine());
int start = Integer.parseInt(st.nextToken());
int end = Integer.parseInt(st.nextToken());
nodeArr[start].adjList.add(end);
nodeArr[start].outDegree +=1;
nodeArr[end].inDegree += 1;
}
topologicalOrder();
System.out.println(ANS);
}
}
static void topologicalOrder() {
Queue<Integer> queue = new LinkedList<Integer>();
for(int i=1;i<=N;i++) {
if(nodeArr[i].inDegree==0) {
nodeArr[i].cost = nodeArr[i].val;
queue.add(i);
}
}
ANS = (long)Integer.MIN_VALUE;
while(!queue.isEmpty()) {
int curr = queue.poll();
for(int i=0;i<nodeArr[curr].adjList.size();i++) {
int next = nodeArr[curr].adjList.get(i);
if(nodeArr[next].inDegree==0) {
continue;
}
nodeArr[next].inDegree -= 1;
nodeArr[next].cost = Math.max(nodeArr[next].cost, nodeArr[curr].cost+nodeArr[next].val);
if(nodeArr[next].inDegree==0) {
queue.add(next);
}
}
}
for(int i=1;i<=N;i++) {
if(nodeArr[i].outDegree==0) {
ANS = Math.max(ANS, nodeArr[i].cost);
}
}
}
}
//定义节点对象
class TopologicalNode{
int index; //节点index
int val; //权值
int inDegree; //入度
int outDegree; //出度
int cost; //节点累计权值
ArrayList<Integer> adjList;
TopologicalNode(int index, int val){
this.index = index;
this.val = val;
this.inDegree=0;
this.outDegree=0;
this.cost=Integer.MIN_VALUE;
adjList = new ArrayList<Integer>();
}
}
浙公网安备 33010602011771号