• 【二分图匹配】Plug It In!


    http://codeforces.com/gym/101873
    F

    先对原图跑一遍匈牙利得到原始最大匹配,再遍历每个出度>1的点,考虑若新加入点,能否找到增广路,若可行则答案对应增加

    代码:

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    typedef long long ll;
    const int MAX_V = 2000;
    const int MAX_E = 80000;
    struct Hungary {
    	struct Edge {
    		int to, next;
    	} es[MAX_E];
    	int head[MAX_V];
    	int V, E, match[MAX_V];
    	bool vis[MAX_V];
    
    	void init(int V) {
    		this->V = V;
    		this->E = 0;
    		memset(head, -1, sizeof head);
    	}
    
    	void addEdge(int u, int v) {
    		es[E].to = v;
    		es[E].next = head[u];
    		head[u] = E++;
    	}
    
    	bool dfs(int u) {
    		vis[u] = true;
    		for (int i = head[u]; i != -1; i = es[i].next) {
    			int v = es[i].to, w = match[v];
    			if (w < 0 || !vis[w] && dfs(w)) {
    				match[v] = u;
    				return true;
    			}
    		}
    		return false;
    	}
    
    	int maxMatch() {
    		int res = 0;
    		memset(match, -1, sizeof match);
    		for (int u = 0; u < V; u++) {
    			memset(vis, false, sizeof vis);
    			if (dfs(u)) {
    				res++;
    			}
    		}
    		return res;
    	}
    } hun;
    int main() {
    	int m, n, k, out[2000] = { 0 }, match[2000] = { 0 };
    	scanf("%d%d%d", &m, &n, &k);
    	hun.init(m);
    	for (int i = 0; i < k; i++) {
    		int u, v;
    		scanf("%d%d", &u, &v);
    		hun.addEdge(u - 1, v - 1);
    		out[u - 1]++;
    	}
    	int res = hun.maxMatch();
    	int ans = res;
    	memcpy(match, hun.match, sizeof hun.match);
    	for (int u = 0; u < m; u++) {
    		if (out[u] > 1) {
    			memcpy(hun.match, match, sizeof match);
    			int cnt = 0;
    			for (int j = 0; j < 2; j++) {
    				hun.head[m + j] = -1;
    				for (int i = hun.head[u]; ~i; i = hun.es[i].next) {
    					int v = hun.es[i].to;
    					hun.addEdge(m + j, v);
    					cnt++;
    				}
    			}
    			hun.E -= cnt;
    			int extra = 0;
    			for (int j = 0; j < 2; j++) {
    				memset(hun.vis, 0, sizeof hun.vis);
    				if (hun.dfs(m + j)) {
    					extra++;
    				}
    			}
    			ans = max(ans, res + extra);
    		}
    	}
    	printf("%d
    ", ans);
    }
  • 相关阅读:
    Thinkphp5 对接百度云对象存储 BOS (上传、删除)
    php 删除富文本编辑器保存内容中的其他代码(保留中文)
    ffmreg thinkphp 控制器 获取音频视频详细信息(获取时长)
    selenium+testng+java+poi进行excel的数据参数化
    linux中磁盘配额管理
    linux中挂载和卸载文件系统
    linux中vi编辑器的练习
    Linux基础命令
    Nginx流量复制
    Python脚本
  • 原文地址:https://www.cnblogs.com/stolf/p/9640980.html
Copyright © 2020-2023  润新知