zoukankan      html  css  js  c++  java
  • 【二分图匹配】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);
    }
  • 相关阅读:
    Windows Store App 主题动画
    Windows Store App 过渡动画
    Windows Store App 控件动画
    Windows Store App 近期访问列表
    Windows Store App 文件选取器
    Windows Store App 访问应用内部文件
    Windows Store App 用户库文件分组
    Windows Store App 获取文件及文件夹列表
    Windows Store App 用户库文件夹操作
    Windows Store App 用户库文件操作
  • 原文地址:https://www.cnblogs.com/stolf/p/9640980.html
Copyright © 2011-2022 走看看