您的位置:首页 > 其它

POJ 刷题系列:1459. Power Network

2018-01-08 21:28 323 查看

POJ 刷题系列:1459. Power Network

传送门:1459. Power Network

题意:

给你n个点,其中有np个是能提供电力的点,nc个是能消费电力的点,剩下的点(n-np-nc)是中转战即不提供电力也不消费电力,点与点之间是有线路存在的,有m条线路,每条线路有最多运载限定。

前4个数据就是有n个点,np个供电点,nc个消费点,m条线路,接来题目先给出的是m条线路的数据,(起点,终点)最多运载量,然后是np个供电点的数据(供电点)最多供电量,接着就是nc个消费点的数据(消费点)最多消费电量。 题目要我们求出给定的图最大能消费的总电量(就是求最大流).

思路:

最大流模版题,不多说。虚拟出源点0和汇点n+1,将发电厂与源点相连,将用户和汇点相连,然后便可以直接求最大流。采用DINIC算法。

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main{

String INPUT = "./data/judge/201801/P1459.txt";
static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));

static int nextInt() throws IOException {
in.nextToken();
return (int)in.nval;
}

static int next() throws IOException {
in.nextToken();
in.nextToken();
return (int) in.nval;
}

public static void main(String[] args) throws IOException {
new Main().read();
}

class Edge{
int to;
int cap;
int rev;

Edge(int to, int cap, int rev){
this.to  = to;
this.cap = cap;
this.rev = rev;
}

@Override
public String toString() {
return "(" + to + ", " + cap + "," + rev + ")";
}
}

static final int INF = 0x3f3f3f3f;

List<Edge>[] graph;
int[] level;

void addEdge(int from, int to, int cap) {
graph[from].add(new Edge(to, cap, graph[to].size()));
graph[to].add(new Edge(from, 0, graph[from].size() - 1));
}

void bfs(int s, int to) {
Arrays.fill(level, -1);
Queue<Integer> q = new ArrayDeque<Integer>();
level[s] = 0;
q.offer(s);
while (!q.isEmpty()) {
int now = q.poll();
for (Edge e : graph[now]) {
if (level[e.to] < 0 && e.cap > 0) {
level[e.to] = level[now] + 1;
q.offer(e.to);
}
}
}
}

int dfs(int s, int v, int f, boolean[] vis) {
if (s == v) return f;
vis[s] = true;
for (Edge e : graph[s]) {
int to  = e.to;
if (!vis[to] && e.cap > 0 && level[s] + 1 == level[to]) {
int d = dfs(to, v, Math.min(f, e.cap), vis);
if (d > 0) {
e.cap -= d;
graph[to].get(e.rev).cap += d;
return d;
}
}
}
return 0;
}

int dinic(int s, int to, int V) {
int flow = 0;
for(;;) {
bfs(s, to);
if (level[to] < 0) break;
int f = 0;
while ((f = dfs(s, to, INF, new boolean[V])) > 0) flow += f;
}
return flow;
}

void read() throws IOException {
while(in.nextToken() != StreamTokenizer.TT_EOF) {
int n  = (int) in.nval;  // n 个顶点
int np = nextInt();  // power stations
int nc = nextInt();  // consumers
int m  = nextInt();  // power stations line

graph = new ArrayList[n + 2];
level = new int[n + 2];
for (int i = 0; i < n + 2; ++i) graph[i] = new ArrayList<Edge>();
for (int i = 0; i < m; ++i) {
addEdge(next() + 1, next() + 1, next());
}

for (int i = 0; i < np; ++i) {
addEdge(0, next() + 1, next());
}

for (int i = 0; i < nc; ++i) {
addEdge(next() + 1, n + 1, next());
}

System.out.println(dinic(0, n + 1, n + 2));
}
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: