• 洛谷 P5540


    题目链接:P5540 最小乘积生成树

    题目大意

    题目中已经描述的很清楚了/笑哭

    solution

    艹,不会

    参考自:solution

    code:

    /**
    *    Author: Alieme
    *    Data: 2020.8.30
    *    Problem: P5540
    *    Time: O()
    */
    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    
    #define int long long
    #define rr register
    
    #define inf 1e9
    #define MAXN 100010
    
    using namespace std;
    
    inline int read() {
    	int s = 0, f = 0;
    	char ch = getchar();
    	while (!isdigit(ch)) f |= ch == '-', ch = getchar();
    	while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
    	return f ? -s : s;
    }
    
    void print(int x) {
    	if (x < 0) putchar('-'), x = -x;
    	if (x > 9) print(x / 10);
    	putchar(x % 10 + 48);
    }
    
    struct UFS {
    	int fa[MAXN];
    	inline void init(int n) {for(rr int i = 1; i <= n; i++) fa[i] = i;}
    	int find(int x) {return x == fa[x] ? x : fa[x] = find(fa[x]);}
    	inline bool check(int x, int y) {return find(x) == find(y);}
    	inline void merge(int x, int y) {x = find(x), y = find(y); if (x != y) fa[x] = y;}
    }S;
    
    struct Gragh {
    	int u, v, a, b, w;
    	bool operator < (const Gragh &b) const {return w < b.w;}
    }g[MAXN];
    
    struct Point {
    	int x, y;
    	Point() {}
    	Point(int X, int Y) {x = X, y = Y;}
    	Point operator -(const Point &b) const { return Point(x - b.x, y - b.y);}
    };
    
    int n, m;
    
    Point ans = Point(inf, inf);
    
    inline int cross(Point a, Point b) {return a.x * b.y - a.y * b.x;}
    
    inline Point kruskal() {
    	Point res = Point(0, 0);
    	int tot = 0;
    	sort(g + 1, g + 1 + m);
    	S.init(n);
    	for (rr int i = 1; i <= m; i++) {
    		int u = g[i].u, v = g[i].v, a = g[i].a, b = g[i].b;
    		if (S.check(u, v)) continue;
    		S.merge(u, v);
    		res.x += a;
    		res.y += b;
    		tot++;
    		if (tot == n - 1) break;
    	}
    	int sum = ans.x * ans.y, now = res.x * res.y;
    	// cout << sum << " " << now << "
    ";
    	if (sum > now || (sum == now && ans.x > res.x)) ans = res;
    	return res;
    }
    
    void solve(Point A, Point B) {
    	for (rr int i = 1; i <= m; i++) g[i].w = g[i].b * (B.x - A.x) + g[i].a * (A.y - B.y);
    	Point C = kruskal();
    	if (cross(B - A, C - A) >= 0) return ;
    	solve(A, C);
    	solve(C, B);
    }
    
    signed main() {
    	n = read();
    	m = read();
    	for (rr int i = 1; i <= m; i++) {
    		g[i].u = read() + 1;
    		g[i].v = read() + 1;
    		g[i].a = read();
    		g[i].b = read();
    	}
    	for (rr int i = 1; i <= m; i++) g[i].w = g[i].a;
    	Point A = kruskal();
    	for (rr int i = 1; i <= m; i++) g[i].w = g[i].b;
    	Point B = kruskal();
    	solve(A, B);
    	cout << ans.x << " " << ans.y << "
    ";
    }
    
  • 相关阅读:
    MapReduce-shuffle过程详解
    YARN中的失败分析
    HBase协处理器的使用(添加Solr二级索引)
    Flume具体应用(多案例)
    Flume架构及运行机制
    python Cmd实例之网络爬虫应用
    mongodb3 权限认证问题总结
    webpack配置
    apt软件包管理
    python笔记之编程风格大比拼
  • 原文地址:https://www.cnblogs.com/lieberdq/p/13590255.html
Copyright © 2020-2023  润新知