zoukankan      html  css  js  c++  java
  • 题解 UVA753 【UNIX插头 A Plug for UNIX】

    题目简述

    有 n 个插座,m 个设备和 k (n, m, k ≤ 100) 种转换器,每种转换器有无限多。已知每个插座的类型,每个设备的插头类型,以及每种转换器的插座类型和插头类型。插头和插座类型都用不超过 2424 个字母表示,插座只能插到类型名称相同的插座中。

    例如,有 4 个插座,类型分别为 A,B,C,D;有 5 个设备,插头类型分别为 B,C,B,B,X;还有三种转换器,分别是 B->X,X->A 和 X->D。这里用 B -> X 表示插座类型为 B,插头类型为 X,因此一个插座类型为 B 的设备插上这种转换器之后就 “变成” 了一个插头类型为 X 的设备。转换器可以级联使用,例如插头类型为 A 的设备依次接上 A->B, B->C, C->D 这 3 个转换器之后会 “变成” 插头类型为 D 的设备。

    要求插的设备尽量多。问最少剩几个不匹配的设备。

    主要思路 :最大流 (此处采用Dinic算法)

    Dinic的模板就不仔细讲了,有需要的的同学去网络最大流题解中去看,我这里的Dinic是从第一篇题解中学来的,代码有些相似。

    这道题最重要的是建图(似乎网络流的题都是这样吧)。

    我们建立一个 s = 0 作为源点,既然我们要从抽象的从设备到插座连边,也就是说从设备流入图中,既然我们每个设备只能算 1 ,我们就讲 s 向每一个设备连一条容量为 1 的边。相似的,我们要流到每个插座,最终插座流向汇点 t = n + m + k + 1(n + m + k是题目中所给的可能最大的节点数,为了不重复,我们定的大一些),便于统计答案。

    然后处理插座,设备与转换器的关系。

    首先是设备,设备可以直接连到插座上,也可以连到转换器上,我们就把接口名字相同的连接起来。然后处理转换器,转换器还可以连转换器,也可以直接连到插座上,也是把名字相同的连接起来,切记,不要把同一个转换器首尾连接(好像可能性不大)。

    然后跑个最大流,源点 s 汇点 t。

    最后,UVa的毒瘤输出,,,注意代码最后的main函数,,,

    code

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <string>
    using namespace std;
    #define go(i, j, n, k) for(int i = j; i <= n; i += k)
    #define rep(i, x) for(int i = h[x]; i != -1; i = e[i].nxt)
    #define curep(i, x) for(int i = cur[x]; i != -1; i = e[i].nxt)
    #define mn 100010
    #define inf 1 << 30
    inline int read(){
    	int x = 0, f = 1; char ch = getchar();
    	while(ch > '9' || ch < '0') { if(ch == '-') f = -f; ch = getchar(); }
    	while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    	return x * f;
    }
    
    int n, m, K;
    struct edge {
    	int v, nxt, w;
    } e[mn << 1];
    int h[mn], p = -1;
    inline void add(int a, int b, int c) {
    	e[++p].nxt = h[a], h[a] = p;
    	e[p].v = b, e[p].w = c; 
    	e[++p].nxt = h[b], h[b] = p;
    	e[p].v = a, e[p].w = 0;  
    }
    int dep[mn], cur[mn]; 
    string na[mn], naa[mn], name1[mn], name2[mn];
    
    inline bool bfs(int s, int t) {
    	go(i, 0, n + m + K + 1, 1) dep[i] = inf;
    	go(i, 0, n + m + K + 1, 1) cur[i] = h[i];
    	queue<int> q;
    	dep[s] = 0;
    	q.push(s);
    	while(!q.empty()) {
    		int x = q.front(); q.pop();
    		rep(i, x) {
    			int v = e[i].v, w = e[i].w;
    			if(dep[v] >= inf && w) {
    				dep[v] = dep[x] + 1;
    				q.push(v);
    			}
    		}
    	}
    	if(dep[t] < inf) return true;
    	return false;
    }
    
    int dfs(int x, int t, int lim) { 
    	if(!lim || x == t) return lim;
    	int flow = 0, f = 0;
    	curep(i, x) {
    		int v = e[i].v, w = e[i].w;
    		cur[x] = i;
    		if(dep[v] == dep[x] + 1 && (f = dfs(v, t, min(lim, w)))) {
    			flow += f;
    			lim -= f;
    			e[i].w -= f;
    			e[i ^ 1].w += f;
    			if(!lim) break;
    		}
    	} 
    	return flow;
    }
    
    inline int Dinic(int s, int t) {
    	int maxflow = 0;
    	while(bfs(s, t)) 
    		maxflow += dfs(s, t, inf); 
    	return maxflow;
    }
    
    inline void solve() {
    	n = read();
    	go(i, 1, n, 1) {
    		cin >> na[i];
    	}
    	m = read();
    	go(i, 1, m, 1) {
    		string tmp; cin >> tmp;
    		cin >> naa[i];
    	}
    	K = read();
    	go(i, 1, K, 1) {
    		cin >> name1[i] >> name2[i];
    	}
    	int s = 0, t = n + m + K + 1;
    	go(i, 1, n, 1) {
    		add(i, t, 1);
    	} 
    	go(i, 1, m, 1) {
    		add(s, i + n, 1);
    		go(j, 1, n, 1) {
    			if(naa[i] == na[j])
    				add(i + n, j, 1);
    		}
    		go(j, 1, K, 1) {
    			if(naa[i] == name1[j])
    				add(i + n, j + n + m, 1e9);
    		}
    	}
    	go(i, 1, K, 1) {
    		go(j, 1, n, 1) {
    			if(name2[i] == na[j])
    				add(i + n + m, j, 1e9);
    		} 
    		go(j, 1, K, 1) {
    			if(name2[i] == name1[j] && i != j) {
    				add(i + n + m, j + n + m, 1e9);
    			}
    		}
    	}
    	int ans = Dinic(s, t);
    	cout << m - ans << "
    ";
    }
    inline void init() {
    	memset(h, -1, sizeof h);
    	p = -1;
    }
    int main(){
    	int T = read();
    	while(T--) {
    		init();
    		solve();
    		if(T) puts("");
    	}
    	return 0;
    }
    
  • 相关阅读:
    [转] 64位Oracle 11g R2的客户端连接时报ORA-01019错误
    [转]Oracle11g链接提示未“在本地计算机注册“OraOLEDB.Oracle”解决方法
    [转]通过Net Manager 配置Oracle 11g本地监听服务(listener service)
    [转]jQuery Mobile动态刷新页面样式
    [转]SSIS
    [转]在SSIS中,使用“包配置”时的常见错误与解析
    使用JMH做Java微基准测试
    秒杀系统解决方案
    cookie机制和session机制
    app如何节省流量
  • 原文地址:https://www.cnblogs.com/yizimi/p/10582041.html
Copyright © 2011-2022 走看看