Problem:
MathJax.Hub.Config({ tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]} });

E: 敵襲から守れ

問題

島が $V$ 島あり、それぞれ $0, 1, ..., V-1$ と番号がついている。橋が $E$ 本あり、それぞれ $0, 1, ..., E-1$ と番号がついている。 $i$ 番目の橋は島 $s_i$ と島 $t_i$ にかかってあり、幅は $c_i$ である。

島 $0$ に基地があるAORイカちゃん軍団 (通称イカ団) は規模が弱小であるため、島 $V-1$ にあるSosu-Usa軍団 (通称そすうさ団) にいつもやられっぱなしである。ある日、イカ団は「そすうさ団が明日攻めてくる」との情報を得た。そすうさ団の基地から大人数のそすうさ団の部下が橋を渡って島を移動し、部下が一人でもイカ団の基地にたどり着かれるとイカ団は滅びてしまう……。

そこでイカ団は橋に通行止めテープを張ることで橋を通れないようにし、危機を免れようとした。使うテープの長さは通行止めにした橋の幅の総和である。また、そすうさ団の部下全員が必ずある一本の幅 $1$ の橋を通る場合、イカ団がそこで待ち伏せすることで、そすうさ団を通れなくすることができる。

保持しているテープの長さは $10^4$ である。今後のことも考え、消費するテープの量はなるべく少なくしたい。そすうさ団の部下がイカ団の基地にたどり着けないようにするために使うテープの長さの最小値を求めよ。ただし、テープの長さが足りずどうしても攻められてしまう合は
$-1$ を出力せよ。

制約

$2 \le V \le 5 \times 10^3$

$1 \le E \le min(5 \times 10^3, V(V-1)/2)$

$1 \le c_i \le 5 \times 10^3$

$0 \le s_i, t_i \lt V$

与えられるグラフは連結かつ単純である。

入力は全て整数で与えらえる。

入力形式

入力は以下の形式で与えられる。

$V \ E$
$s_0 \ t_0 \ c_0$
$s_1 \ t_1 \ c_1$
$\vdots$
$s_{E-1} \ t_{E-1} \ c_{E-1}$

出力

そすうさ団の部下がイカ団の基地にたどり着けないようにするために使うテープの長さの最小値を出力せよ。ただし、テープの長さが足りずどうしても攻められてしまう場合は $-1$ を出力せよ。また、末尾に改行も出力せよ。

サンプル

サンプル入力 1

4 4
0 1 3
0 2 4
1 3 1
2 3 5

サンプル出力 1

4

イカ団は $2$ 番目の橋で待ち伏せし、$1$ 番の橋にテープを貼ることで、そすうさ団を止められる。

サンプル入力 2

2 1
0 1 100

サンプル出力 2

100

$0$ 番目の橋にテープを貼ることで、そすうさ団を止められる。 橋の幅が $1$ でないため、待ち伏せはできない。

サンプル入力 3

5 6
0 1 5000
0 2 5000
0 3 5000
1 4 5000
2 4 5000
3 4 5000

サンプル出力 3

-1

テープが足りないため、どのようにテープを貼ってもそうすさ団は止められない。

Solution in C# (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Globalization;
using System.Diagnostics;



class Myon
{
    public Myon() { }
    public static int Main()
    {
        new Myon().calc();
        return 0;
    }

    Scanner cin;

    void calc()
    {
        cin = new Scanner();
        int N = cin.nextInt();
        int M = cin.nextInt();
        int[] s = new int[M];
        int[] t = new int[M];
        long[] c = new long[M];

        long mul = 1000000000;

        for (int i = 0; i < M; i++)
        {
            s[i] = cin.nextInt();
            t[i] = cin.nextInt();
            c[i] = cin.nextInt() * mul;
            if (c[i] == mul) c[i]--;
        }

        V[] vs = new V[N];
        for (int i = 0; i < N; i++)
        {
            vs[i] = new V();
        }

        for (int i = 0; i < M; i++)
        {
            vs[s[i]].add(vs[t[i]], c[i]);
            vs[t[i]].add(vs[s[i]], c[i]);
        }

        long ans = dinic(vs[0], vs[N - 1]);
        ans /= mul;
        if (ans > 10000) Console.WriteLine(-1);
        else Console.WriteLine(ans);
    }

    long INF = 1L << 62;
    long dinic(V s, V t)
    {
        long flow = 0;
        for (int p = 1; ; p++)
        {
            Queue<V> que = new Queue<V>();
            s.level = 0;
            s.p = p;
            que.Enqueue(s);
            while (que.Count != 0)
            {
                V v = que.Dequeue();
                v.iter = v.es.Count - 1;
                foreach (E e in v.es)
                {
                    if (e.to.p < p && e.cap > 0)
                    {
                        e.to.level = v.level + 1;
                        e.to.p = p;
                        que.Enqueue(e.to);
                    }
                }
            }
            if (t.p < p) return flow;
            for (long f = 0; (f = dfs(s, t, INF)) > 0;)
            {
                flow += f;
            }
        }
    }

    long dfs(V v, V t, long f)
    {
        if (v == t) return f;
        for (; v.iter >= 0; v.iter--)
        {
            E e = v.es[v.iter];
            if (v.level < e.to.level && e.cap > 0)
            {
                long d = dfs(e.to, t, Math.Min(f, e.cap));
                if (d > 0)
                {
                    e.cap -= d;
                    e.rev.cap += d;
                    return d;
                }
            }
        }
        return 0;
    }

    class V
    {
        public V() { }
        public List<E> es = new List<E>();
        public int level, p, iter;
        public void add(V to, long cap)
        {
            E e = new E(to, cap);
            E rev = new E(this, 0);
            e.rev = rev;
            rev.rev = e;
            es.Add(e);
            to.es.Add(rev);
        }
    }

    class E
    {
        public V to;
        public E rev;
        public long cap;
        public E(V to, long cap)
        {
            this.to = to;
            this.cap = cap;
        }

    } 
}


class Scanner
{
    string[] s;
    int i;

    char[] cs = new char[] { ' ' };

    public Scanner()
    {
        s = new string[0];
        i = 0;
    }

    public string next()
    {
        if (i < s.Length) return s[i++];
        string st = Console.ReadLine();
        while (st == "") st = Console.ReadLine();
        s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
        if (s.Length == 0) return next();
        i = 0;
        return s[i++];
    }

    public int nextInt()
    {
        return int.Parse(next());
    }
    public int[] ArrayInt(int N, int add = 0)
    {
        int[] Array = new int[N];
        for (int i = 0; i < N; i++)
        {
            Array[i] = nextInt() + add;
        }
        return Array;
    }

    public long nextLong()
    {
        return long.Parse(next());
    }

    public long[] ArrayLong(int N, long add = 0)
    {
        long[] Array = new long[N];
        for (int i = 0; i < N; i++)
        {
            Array[i] = nextLong() + add;
        }
        return Array;
    }

    public double nextDouble()
    {
        return double.Parse(next());
    }


    public double[] ArrayDouble(int N, double add = 0)
    {
        double[] Array = new double[N];
        for (int i = 0; i < N; i++)
        {
            Array[i] = nextDouble() + add;
        }
        return Array;
    }
}