• 洛谷 P1401 城市


    写在前面

    今天来水主题库里的有水分的紫题,随便一翻竟然找到宝了。

    小清新二分 + 网络流。

    算法思路

    考虑到题目中限制的是最大边权,要求最大边权最小,那么很容易想到二分答案。

    单调性的证明:最大边权是对可行的边的一个限制,因此这个值越大,对可行的边的限制放的就越宽,可供选择的边就不会变少。凑齐 (t) 条边的机会不会变小。满足单调性。

    考虑到要找到 (t) 条可行路径,可以抽象成为在所有边权的容量都为 (1) 的情况下,最大流不小于 (t)

    求解最大流这里我使用的 dinic 算法。

    dinic 算法的时间复杂度为 (mathcal O(n^2m)),实际上远远跑不满,而且它有各种虽然不影响渐进时间复杂度,但是能够大大提高实际运行效率的优化和剪枝。因此实际运行效率极高。

    Tips

    • 注意存双向边、数组越界和每次清空。

    Code

    #include <bits/stdc++.h>
    
    namespace Basic {
    	template <typename Temp> inline void read(Temp & res) {
    		Temp fh = 1; res = 0; char ch = getchar();
    		for(; !isdigit(ch); ch = getchar()) if(ch == '-') fh = -1;
    		for(; isdigit(ch); ch = getchar()) res = (res << 3) + (res << 1) + (ch ^ '0');
    		res = res * fh;
    	}
    }
    
    using namespace Basic;
    using namespace std;
    
    const int Maxn = 2e2 + 5;
    const int Maxm = 8e4 + 5;
    
    int n, m, t, x, y, z;
    int l = 0, r = 0x7fffffff, mid, ans;
    
    struct e {
    	int to, nxt, f;
    } b[Maxm];
    int head[Maxn], ecnt;
    inline void add(int u, int v, int fl) {b[++ecnt] = (e) {v, head[u], fl}; head[u] = ecnt;}
    
    struct edg {
    	int v_1, v_2, length;
    } b0[Maxm];
    
    queue<int> q;
    int dep[Maxn], cur[Maxn];
    bool bfs() {
    	memset(dep, 0, sizeof(dep));
    	while(!q.empty()) q.pop();
    	q.push(1); dep[1] = 1;
    	while(!q.empty()) {
    		int tnow = q.front(); q.pop();
    		for(register int i = head[tnow]; i; i = b[i].nxt) {
    			int tto = b[i].to, tf = b[i].f;
    			if((dep[tto]) || (!tf)) continue;
    			dep[tto] = dep[tnow] + 1;
    			q.push(tto);
    			if(tto == n) return true;
    		}
    	}
    	return false;
    }
    
    int dfs(int t, int flow) {
    	if(t == n) return flow;
    	int rest = flow;
    	for(; cur[t] && rest; cur[t] = b[cur[t]].nxt) {
    		int tto = b[cur[t]].to, tf = b[cur[t]].f;
    		if((dep[tto] != dep[t] + 1) || (!tf)) continue;
    		int res = dfs(tto, min(tf, rest));
    		rest -= res; b[cur[t]].f -= res; b[cur[t] ^ 1].f += res;
    		if(!res) dep[tto] = 0;
    		if(!rest) return flow;
    	}
    	return flow - rest;
    }
    
    bool check(int lim) {
    	int Maxflow = 0;
    	memset(head, 0, sizeof(head)); ecnt = 1;
    	for(register int i = 1; i <= m; ++i) {
    		if(b0[i].length <= lim) {
    			add(b0[i].v_1, b0[i].v_2, 1);
    			add(b0[i].v_2, b0[i].v_1, 1);
    		}
    	}
    	while(bfs()) {
    		memcpy(cur, head, sizeof(cur));
    		Maxflow += dfs(1, 0x7fffffff >> 1);
    	}
    	return Maxflow >= t;
    }
    
    int main() {
    	read(n); read(m); read(t);
    	for(register int i = 1; i <= m; ++i) {read(b0[i].v_1); read(b0[i].v_2); read(b0[i].length);}
    	while(l <= r) {
    		int mid = (l + r) >> 1;
    		if(check(mid)) ans = mid, r = mid - 1;
    		else l = mid + 1; 
    	}
    	printf("%d", ans);
    	return 0;
    } 
    
  • 相关阅读:
    TensorFlow笔记-05-反向传播,搭建神经网络的八股
    TensorFlow笔记-04-神经网络的实现过程,前向传播
    TensorFlow笔记-03-张量,计算图,会话
    TensorFlow笔记-02-Windows下搭建TensorFlow环境(win版非虚拟机)
    TensorFlow笔记-01-开篇概述
    Tesseract-OCR-05-主要API功能介绍
    关于博客园美化装修
    Tesseract-OCR-04-使用 jTessBoxEditor 进行训练
    Tesseract-OCR-03-图片文字识别
    Tesseract-OCR-02-Tesseract-OCR 的安装与 环境变量配置
  • 原文地址:https://www.cnblogs.com/zimujun/p/14258004.html
Copyright © 2020-2023  润新知