UVa 753 - A Plug for UNIX (网络流)

题目链接:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=0&problem=694&mosmsg=Submission+received+with+ID+26555189

将所有插头类型看成点,从源点向设备连边,容量为 \(1\), 从插座向汇点连边,容量为 \(1\),转换器的插头间连边,容量为 \(INF\)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 405;
const int INF = 1000000007;

int T, n, N, M, K, ans;
int target[maxn], device[maxn], from[maxn], to[maxn];

vector<string> names;
int ID(const string s){
	for(int i = 0 ; i < names.size() ; i++){
		if(names[i] == s) return (i + 1);
	}
	names.push_back(s);
	return names.size();
}

int h[maxn], cnt = 1;
struct Edge{
	int from, to, cap, flow, next;
}e[(maxn * maxn)<< 1];
void add(int u, int v, int c){
	e[++cnt].to = v;
	e[cnt].cap = c;
	e[cnt].next = h[u];
	h[u] = cnt; 
}

int d[maxn];
queue<int> q;
int s, t;

int bfs(){

	while(!q.empty()) q.pop();
	memset(d,0,sizeof(d));
	d[s] = 1;
	q.push(s);
	while(!q.empty()){
		int u = q.front(); q.pop();
		for(int i = h[u] ; i != -1 ; i = e[i].next){
			int v = e[i].to;
			if(!d[v] && e[i].cap){
				d[v] = d[u] + 1;
				q.push(v);
			}
		}
	}
	return d[t];
} 

int dfs(int u,int lim){
	if(u==t) return lim;
	int f=0,tmp;
	for(int i=h[u];i!=-1;i=e[i].next){
		int v=e[i].to;
		if(d[v]==d[u]+1&&e[i].cap&&(tmp=dfs(v,min(lim,e[i].cap)))){
			e[i].cap-=tmp; e[i^1].cap+=tmp;
			f+=tmp; lim-=tmp;
			if(!lim) return f;
		}
	}
	if(lim) d[u]=0;
	return f;
}

void dinic(){
	ans=0;
	while(bfs()){
		ans+=dfs(s,INF);
	}
}

ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }

int main(){
	cin >> T;
	int flag = 0;
	while(T--){
		if(flag) printf("\n");
		flag = 1;
		ans = 0;
		
		names.clear(); 
		memset(d, 0, sizeof(d));
		memset(h, -1, sizeof(h));
		cnt = 1;
		
		string s1, s2;
		cin >> N;
		for(int i = 1 ; i <= N ; ++i){
			cin >> s1;
			target[i] = ID(s1);
		}		
		
		cin >> M;
		for(int i = 1 ; i <= M ; ++i){
			cin >> s1 >> s2;
			device[i] = ID(s2);
		}
		
		cin >> K;
		for(int i = 1 ; i <= K ; ++i){
			cin >> s1 >> s2;
			from[i] = ID(s1);
			to[i] = ID(s2);
		}
		
		n = names.size();
		for(int i = 1 ; i <= M ; ++i){ // 源点 -> 设备 
			add(n + 1, device[i], 1);
			add(device[i], n + 1, 0);
		}
		
		for(int i = 1 ; i <= N ; ++i){ // 插座 -> 汇点 
			add(target[i], n + 2, 1);
			add(n + 2, target[i], 0); 			
		}
		
		for(int i = 1 ; i <= K ; ++i){ // 插头 -> 插头 
			add(from[i], to[i], INF);
			add(to[i], from[i], 0); 
		} 
		s = n + 1, t = n + 2;
		
		dinic();
		
		printf("%d\n", M - ans);
	}
	return 0;
}
posted @ 2021-07-09 18:54  Tartarus_li  阅读(32)  评论(0编辑  收藏  举报