Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io.BufferedReader;
- import java.io.FileNotFoundException;
- import java.io.FileReader;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.util.ArrayList;
- import java.util.StringTokenizer;
- import java.util.TreeSet;
- public class chinese_sm_slow {
- class Refrigerator {
- ArrayList<Integer>[] eto, efrom;
- int[] u;
- int[] ans;
- int[] cond;
- int cnt;
- void dfs(int v) {
- u[v] = 1;
- for (int i : efrom[v]) {
- if (u[i] == 0) {
- dfs(i);
- }
- }
- u[v] = 2;
- ans[--cnt] = v;
- }
- void dfs2(int v, int c) {
- u[v] = 1;
- cond[v] = c;
- for (int i : eto[v]) {
- if (u[i] == 0) {
- dfs2(i, c);
- }
- }
- u[v] = 2;
- }
- int n;
- @SuppressWarnings("unchecked")
- public Refrigerator(int n) {
- this.n = n;
- eto = new ArrayList[n];
- efrom = new ArrayList[n];
- for (int i = 0; i < n; i++) {
- eto[i] = new ArrayList<Integer>(1);
- efrom[i] = new ArrayList<Integer>(1);
- }
- // for (int i = 0; i < m; i++) {
- // int x = nextInt() - 1;
- // int y = nextInt() - 1;
- // eto[x].add(y);
- // efrom[y].add(x);
- // }
- }
- int[] solve() {
- u = new int[n];
- ans = new int[n];
- cnt = n;
- for (int i = 0; i < n; i++) {
- if (u[i] == 0) {
- dfs(i);
- }
- }
- u = new int[n];
- cond = new int[n];
- cnt = 1;
- for (int i = 0; i < ans.length; i++) {
- if (u[ans[i]] == 0) {
- dfs2(ans[i], cnt++);
- }
- }
- for (int i = 0; i < cond.length; i++) {
- cond[i] = cnt - cond[i] - 1;
- }
- // Arrays.fill(u, -1);
- // for (int i = 0; i < cond.length; i++) {
- // if (u[cond[i]] == -1) {
- // u[cond[i]] = i;
- // }
- // }
- // for (int i = 0; i < cond.length; i++) {
- // cond[i] = u[cond[i]];
- // }
- cnt--;
- return cond;
- }
- }
- class Edge implements Comparable<Edge> {
- int from, to, c;
- int sourceC;
- Edge parent;
- public Edge(int from, int to, int c) {
- this.c = c;
- this.from = from;
- this.to = to;
- sourceC = c;
- }
- public Edge(int from, int to, Edge e) {
- this.from = from;
- this.to = to;
- this.c = e.c;
- this.sourceC = e.sourceC;
- this.parent = e;
- }
- @Override
- public int compareTo(Edge o) {
- if (from < o.from)
- return -1;
- if (from > o.from)
- return 1;
- if (to < o.to)
- return -1;
- if (to > o.to)
- return 1;
- return 0;
- }
- }
- class Vertex {
- ArrayList<Edge> in, out;
- Edge zeroIn;
- public Vertex() {
- in = new ArrayList<Edge>(1);
- out = new ArrayList<Edge>(1);
- }
- }
- class Kever {
- ArrayList<Integer>[] e2;
- @SuppressWarnings("unchecked")
- public Kever(int n) {
- e2 = new ArrayList[n];
- for (int i = 0; i < e2.length; i++) {
- e2[i] = new ArrayList<Integer>();
- }
- }
- boolean[] u;
- boolean isBald(int x) {
- u = new boolean[e2.length];
- dfs(x);
- for (int i = 0; i < u.length; i++) {
- if (!u[i]) {
- return false;
- }
- }
- return true;
- }
- void dfs(int v) {
- u[v] = true;
- for (int x : e2[v]) {
- if (!u[x]) {
- dfs(x);
- }
- }
- }
- }
- class Graph {
- Vertex[] v;
- int n;
- public Graph(int n) {
- v = new Vertex[n];
- this.n = n;
- all = new TreeSet<Edge>();
- select = new TreeSet<Edge>();
- for (int i = 0; i < v.length; i++) {
- v[i] = new Vertex();
- }
- }
- TreeSet<Edge> all;
- TreeSet<Edge> select;
- void addEdge(int from, int to, int c) {
- Edge e = new Edge(from, to, c);
- addEdge(e);
- }
- void addEdge(Edge e) {
- if (e.from == e.to)
- return;
- if (all.contains(e)) {
- if (e.c < all.headSet(e, true).last().c) {
- all.remove(e);
- all.add(e);
- }
- } else {
- all.add(e);
- }
- }
- void solve() {
- for (Edge e : all) {
- v[e.from].out.add(e);
- v[e.to].in.add(e);
- }
- Vertex start = v[0];
- for (Vertex x : v) {
- if (x == start) {
- continue;
- }
- int min = Integer.MAX_VALUE;
- for (Edge e : x.in) {
- min = Math.min(min, e.c);
- }
- for (Edge e : x.in) {
- e.c -= min;
- if (e.c == 0 && x.zeroIn == null) {
- // System.err.println(e.from + " " + e.to + " ("
- // + e.sourceC + ")");
- x.zeroIn = e;
- }
- }
- }
- Refrigerator cond = new Refrigerator(n);
- for (int i = 0; i < v.length; i++) {
- Vertex x = v[i];
- if (x.zeroIn != null) {
- cond.efrom[i].add(x.zeroIn.from);
- cond.eto[x.zeroIn.from].add(i);
- }
- }
- int[] a = cond.solve();
- // System.err.println(Arrays.toString(a));
- // System.err.println(cond.cnt);
- if (cond.cnt != n) {
- Graph g = new Graph(cond.cnt);
- for (Edge e : all) {
- g.addEdge(new Edge(a[e.from], a[e.to], e));
- }
- g.solve();
- for (Edge eNew : g.select) {
- Edge e = eNew.parent;
- v[e.to].zeroIn = e;
- }
- }
- for (int i = 0; i < v.length; i++) {
- Vertex x = v[i];
- if (x.zeroIn != null) {
- select.add(x.zeroIn);
- }
- }
- }
- }
- private void solve() {
- int n = nextInt();
- int m = nextInt();
- Graph g = new Graph(n);
- for (int i = 0; i < m; i++) {
- g.addEdge(nextInt() - 1, nextInt() - 1, nextInt());
- }
- g.solve();
- Kever kever = new Kever(n);
- for (Edge e : g.select) {
- kever.e2[e.from].add(e.to);
- }
- if (!kever.isBald(0)) {
- out.println("NO");
- return;
- } else {
- out.println("YES");
- long ans = 0;
- for (Edge e : g.select) {
- ans += e.sourceC;
- }
- out.println(ans);
- }
- }
- PrintWriter out;
- BufferedReader br;
- StringTokenizer st;
- private void run() {
- try {
- br = new BufferedReader(new FileReader(this.getClass().getName()
- .substring(0, this.getClass().getName().indexOf("_"))
- + ".in"));
- out = new PrintWriter(this.getClass().getName().substring(0,
- this.getClass().getName().indexOf("_"))
- + ".out");
- solve();
- out.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- System.exit(1);
- }
- }
- String nextToken() {
- try {
- while (st == null || !st.hasMoreTokens()) {
- st = new StringTokenizer(br.readLine());
- }
- return st.nextToken();
- } catch (IOException e) {
- return "";
- }
- }
- int nextInt() {
- return Integer.parseInt(nextToken());
- }
- public static void main(String[] args) {
- new chinese_sm_slow().run();
- }
- }
Add Comment
Please, Sign In to add comment