列表

详情


NC16038. 匹配

描述

美团外卖日订单已经超过2000万,背后有一个非常复杂的智能调度系统。
我们考虑一个简化的情形,有n个外卖小哥要去 n 家商店取货,第 i 个外卖小哥到达商店 j 需要时间 e[i][j] 。现在有 m 对外卖小哥和商店的合作关系。假定每个外卖小哥只能取到一个货物,每个商店只需要一位外卖小哥取货。
询问最少多少时间,能有 k 位外卖小哥到达 k 个商店取到货物?对于每个 k ,都输出一个数表示最少使用时间,如果无解输出 -1。

输入描述

第一行输入两个整数 n , m (1 <= n <= 1000 , 1 <= m <= 100000)。
接下来 m 行,每行输入 3 个整数 i , j , e[i][j] (1 <= i, j <= n , 0 <= e[i][j] <= 10^9),定义如题所述。
注:本题测试用例较多,请耐心等待判题结果,也可以去排行榜刷新查看自己的提交结果。

输出描述

输出一行n个整数,第 i 个整数,表示当 k=i 时,需要的最少时间,如果无解输出-1,结尾无空格。

示例1

输入:

3 7
1 3 5
2 3 2
3 1 7
1 2 0
2 3 2
3 2 0
2 1 5

输出:

0 2 5

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Java(javac 1.8) 解法, 执行用时: 2083ms, 内存消耗: 35972K, 提交时间: 2018-10-16 16:51:26

import java.io.*;
import java.util.*;

/**
 * Copyright © 2018 Chris. All rights reserved.
 *
 * @author Chris
 * 2018/10/16 11:23
 * @see format
 */
public class Main {

    private static BufferedReader br;
    private static StreamTokenizer st;
    private static PrintWriter pw;

    static final int INF = 1000000007;
    static final int MOD = 1000000007;

    static int n, m, ans;
    static int dist[], c[], d[], pre[];
    static boolean vst[];
    static List<Integer> edges[];
    static Edge[] a;

    static class Edge {
        int from;
        int to;
        int w;

        Edge(int a, int b, int c) {
            this.from = a;
            this.to = b;
            this.w = c;
        }
    }

    static void dfs1(int x) {
        if (x == 0 || vst[x]) {
            return;
        }
        vst[x] = true;
        int i;
        for (i = 0; i < edges[x].size(); i++) {
            int A = edges[x].get(i);
            if (pre[A] == 0) {
                pre[A] = x;
            }
            dfs1(d[A]);
        }
    }

    static void pre() {
        vst = new boolean[n + 1];
        pre = new int[n + 1];
        for (int i = 1; i <= n; i++) {
            if (c[i] == 0) {
                dfs1(i);
            }
        }
    }

    static int dfs(int x, int y) {
        if (vst[x]) {
            return 0;
        }
        vst[x] = true;
        for (int i = y; i < edges[x].size(); i++) {
            int A = edges[x].get(i);
            if (pre[A] == 0) {
                pre[A] = x;
            }
            if (d[A] == 0 || dfs(d[A], 0) > 0) {
                c[x] = A;
                d[A] = x;
                return 1;
            }
        }
        return 0;
    }

    static void dfs2(int x) {
        if (x == 0) {
            return;
        }
        int A = pre[x];
        int B = c[A];
        c[A] = x;
        d[x] = A;
        dfs2(B);
    }

    static void add(Edge edge) {
        int x = edge.from;
        int y = edge.to;
        edges[x].add(y);
        if (vst[x]) {
            vst[x] = false;
            int z = c[x];
            if (dfs(x, edges[x].size() - 1) > 0) {
                ans++;
                dfs2(z);
                pre();
            }
        }
    }

    @SuppressWarnings("unchecked")
    private static void solve() throws IOException {
        n = nextInt();
        m = nextInt();
        a = new Edge[m + 1];
        c = new int[n + 1];
        d = new int[n + 1];
        dist = new int[n + 1];
        Arrays.fill(dist, -1);
        edges = new List[n + 1];
        vst = new boolean[n + 1];

        a[0] = new Edge(0, 0, -1);
        for (int i = 1; i <= m; i++) {
            a[i] = new Edge(nextInt(), nextInt(), nextInt());
        }
        Arrays.sort(a, Comparator.comparingInt(o -> o.w));
        for (int i = 1; i <= n; i++) {
            edges[i] = new ArrayList<>();
        }
        pre();
        ans = 0;
        for (int i = 1; i <= m; i++) {
            add(a[i]);
            if (dist[ans] < 0) {
                dist[ans] = a[i].w;
            }
            if (ans == n) {
                break;
            }
        }
        for (int i = 1; i <= n; i++) {
            pw.format("%d%c", dist[i], i == n ? '\n' : ' ');
        }
    }

    static int dir1[] = {0, -1, 0, 1, 0};
    static int dir[][] = {{0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}};

    static void getDiv(Map<Long, Integer> map, long n) {
        long sqrt = (long) Math.sqrt(n);
        for (long i = sqrt; i >= 2; i--) {
            if (n % i == 0) {
                getDiv(map, i);
                getDiv(map, n / i);
                return;
            }
        }
        map.put(n, map.getOrDefault(n, 0) + 1);
    }

    // 18's prime:154590409516822759
    // 19's prime:2305843009213693951 (Mersenne primes)
    // 19's prime:4384957924686954497
    static boolean isPrime(long n) { //determines if n is a prime number
        int p[] = {2, 3, 5, 233, 331};
        int pn = p.length;
        long s = 0, t = n - 1;//n - 1 = 2^s * t
        while ((t & 1) == 0) {
            t >>= 1;
            ++s;
        }
        for (int i = 0; i < pn; ++i) {
            if (n == p[i]) {
                return true;
            }
            long pt = pow(p[i], t, n);
            for (int j = 0; j < s; ++j) {
                long cur = llMod(pt, pt, n);
                if (cur == 1 && pt != 1 && pt != n - 1) {
                    return false;
                }
                pt = cur;
            }
            if (pt != 1) {
                return false;
            }
        }
        return true;
    }

    static long llMod(long a, long b, long mod) {
        return (a * b - (long) ((double) a / mod * b + 0.5) * mod + mod) % mod;
//        long r = 0;
//        a %= mod;
//        b %= mod;
//        while (b > 0) {
//            if ((b & 1) == 1) {
//                r = (r + a) % mod;
//            }
//            b >>= 1;
//            a = (a << 1) % mod;
//        }
//        return r;
    }

    static int pow(long a, long n) {
        long ans = 1;
        while (n > 0) {
            if ((n & 1) == 1) {
                ans = (ans * a) % MOD;
            }
            a = (a * a) % MOD;
            n >>= 1;
        }
        return (int) ans;
    }

    static int pow(long a, long n, long mod) {
        long ans = 1;
        while (n > 0) {
            if ((n & 1) == 1) {
                ans = llMod(ans, a, mod);
            }
            a = llMod(a, a, mod);
            n >>= 1;
        }
        return (int) ans;
    }

    public static boolean[] generatePrime(int n) {
        boolean p[] = new boolean[n + 1];
        p[2] = true;

        for (int i = 3; i <= n; i += 2) {
            p[i] = true;
        }

        for (int i = 3; i <= Math.sqrt(n); i += 2) {
            if (!p[i]) {
                continue;
            }
            for (int j = i * i; j <= n; j += i << 1) {
                p[j] = false;
            }
        }
        return p;
    }

    static int gcd(int a, int b) {
        if (a < b) {
            a ^= b;
            b ^= a;
            a ^= b;
        }
        while (b != 0) {
            int tmp = a % b;
            a = b;
            b = tmp;
        }
        return a;
    }

    private static long[][] initC(int n) {
        long c[][] = new long[n][n];

        for (int i = 0; i < n; i++) {
            c[i][0] = 1;
        }

        for (int i = 1; i < n; i++) {
            for (int j = 1; j <= i; j++) {
                c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
            }
        }
        return c;
    }

    static int pow(long a, int n) {
        long ans = 1;
        while (n > 0) {
            if ((n & 1) == 1) {
                ans = (ans * a) % MOD;
            }
            a = (a * a) % MOD;
            n >>= 1;
        }
        return (int) ans;
    }

    /**
     * ps: n >= m, choose m from n;
     */
    private static int c(long n, long m) {
        if (m > n) {
            n ^= m;
            m ^= n;
            n ^= m;
        }
        m = Math.min(m, n - m);

        long top = 1;
        long bot = 1;
        for (long i = n - m + 1; i <= n; i++) {
            top = (top * i) % MOD;
        }
        for (int i = 1; i <= m; i++) {
            bot = (bot * i) % MOD;
        }

        return (int) ((top * pow(bot, MOD - 2)) % MOD);
    }

    static boolean even(long n) {
        return (n & 1) == 0;
    }

    public static void main(String args[]) throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        st = new StreamTokenizer(br);
        pw = new PrintWriter(new OutputStreamWriter(System.out));
        st.ordinaryChar('\'');
        st.ordinaryChar('\"');
        st.ordinaryChar('/');

        long t = System.currentTimeMillis();
        solve();
        pw.flush();
    }

    private static String next(int len) throws IOException {
        char ch[] = new char[len];
        int cur = 0;
        char c;
        int k = br.read();
        if (k == -1) {
            throw new NullPointerException();
        }
        while ((c = (char) k) == '\n' || c == '\r' || c == ' ' || c == '\t') ;
        do {
            ch[cur++] = c;
        } while (!(((k = br.read()) == -1) || (c = (char) k) == '\n' || c == '\r' || c == ' ' || c == '\t'));
        return String.valueOf(ch, 0, cur);
    }

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

    private static long nextLong() throws IOException {
        return Long.parseLong(nextLine());
    }

    private static double nextDouble() throws IOException {
        st.nextToken();
        return st.nval;
    }

    private static String[] nextSS(String reg) throws IOException {
        return br.readLine().split(reg);
    }

    private static String nextLine() throws IOException {
        return br.readLine();
    }
}

C++11(clang++ 3.9) 解法, 执行用时: 398ms, 内存消耗: 4028K, 提交时间: 2018-07-03 19:14:31

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <ctime>
#include <queue>
#include <set>
#include <map>
#define fi first
#define se second
#define PA pair<int,int>
#define VI vector<int>
#define VP vector<PA >
#define mk(x,y) make_pair(x,y)
#define int64 long long
#define db double
#define N 1010
#define M 100010
#define For(i,x,y) for (i=x;i<=y;i++)
using namespace std;
struct ww {
	int a, b, c;
} a[M];
int i, j, k, n, m, t, ans, T;
int b[N], c[N], d[N], pre[N];
bool Rea[N];
VI e[N];

inline bool cc1(const ww &a, const ww &b) {
	return a.c < b.c;
}

void dfs1(int x) {
	if (!x || Rea[x]) return;
	Rea[x] = 1;
	int i;
	for (i = 0; i < e[x].size(); i++) {
		int A = e[x][i];
		if (!pre[A]) pre[A] = x;
		dfs1(d[A]);
	}
}
inline void Pre() {
	memset(Rea, 0, sizeof(Rea));
	memset(pre, 0, sizeof(pre));
	int i;
	For(i, 1, n) if (!c[i]) dfs1(i);
}
int dfs(int x, int y) {
	if (Rea[x]) return 0;
	Rea[x] = 1;
	int i;
	for (i = y; i < e[x].size(); i++) {
		int A = e[x][i];
		if (!pre[A]) pre[A] = x;
		if (!d[A] || dfs(d[A], 0)) {
			c[x] = A;
			d[A] = x;
			return 1;
		}
	}
	return 0;
}
void Dfs(int x) {
	if (!x) return;
	int A = pre[x];
	int B = c[A];
	c[A] = x;
	d[x] = A;
	Dfs(B);
}
inline void Add(ww b) {
	int x = b.a, y = b.b;
	e[x].push_back(y);
	if (Rea[x]) {
		Rea[x] = 0;
		int z = c[x];
		if (dfs(x, e[x].size() - 1)) {
			ans++;
			Dfs(z);
			Pre();
		}
	}
}
int main() {
	scanf("%d%d", &n, &m);
	t = 0;
	For(i, 1, m) {
		int x, y, z;
		scanf("%d%d%d", &x, &y, &z);
		a[++t] = (ww){x, y, z};
	}
	sort(a+1, a+t+1, cc1);
	memset(b, 255, sizeof(b));
	memset(c, 0, sizeof(c));
	memset(d, 0, sizeof(d));
	For(i, 1, n) e[i].clear();
	Pre();
	ans = 0;
	For(i, 1, t) {
		Add(a[i]);
		if (b[ans] < 0) b[ans] = a[i].c;
		if (ans == n) break;
	}
	For(i, 1, n) printf("%d%c", b[i], i == n ? '\n' : ' ');
	return 0;
}

上一题