uva753
Posted 啊嘞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uva753相关的知识,希望对你有一定的参考价值。
题目链接请戳 这里
解题思路
可以用最大流。
建立超级源点与每个设备连接,建立超级汇点与房间里有的插口连接。
至于适配器,注意有的接口房间里可能没有,要新建出来。连接直接在接口上连接,
不需要再建一个“适配器”顶点,因为这个顶点是可以忽略掉的(不清楚就画个图)。
注意适配器连接接口时,其容量为无穷,因为可以搞很多个适配器。其余的容量为1 。
还有,udebug上有个数据貌似是错了(不是uva的那个)。。。
代码
#include<iostream> #include<string.h> #include<string> #include<queue> #include<map> #include<vector> using namespace std; const int N = 1010; const int INF = 1e9; int Flow[N][N], Cap[N][N]; int Pre[N]; int a[N]; //残量 map<string, int> V; //顶点的编号 map<string, string> dv; //设备与插口的映射 vector<string> sock; //接口 bool can[N]; //房间里是否有某个接口 int n, m, k, vcnt; int EK(int s, int t) { queue<int> q; memset(Flow, 0, sizeof(Flow)); int f = 0; while (1) { memset(a, 0, sizeof(a)); a[s] = INF; q.push(s); while (!q.empty()) { int u = q.front(); q.pop(); for (int v = s; v <= t; v++) if (!a[v] && Cap[u][v] > Flow[u][v]) { Pre[v] = u; q.push(v); a[v] = min(a[u], Cap[u][v] - Flow[u][v]); } } if (a[t] == 0) break; for (int u = t; u != s; u = Pre[u]) { Flow[Pre[u]][u] += a[t]; Flow[u][Pre[u]] -= a[t]; } f += a[t]; } return f; } int main() { int tests; cin >> tests; while (tests--) { //记得要初始化哟 memset(Cap, 0, sizeof(Cap)); memset(can, 0, sizeof(can)); sock.clear(); V.clear(); dv.clear(); vcnt = 0; //顶点数 cin >> n; for (int i = 0; i < n; i++) { string s; cin >> s; can[s.front()] = true; //房间里有这个接口 sock.push_back(s); //接口加入到vector中,有重复也没关系 } cin >> m; for (int i = 0; i < m; i++) { string s1, s2; cin >> s1 >> s2; dv[s1] = s2; //设备与接口的映射 V[s1] = ++vcnt; //给设备编号 sock.push_back(s2); //接口加入到vector中 Cap[0][V[s1]] = 1; //超级源与设备连接 } //为收集到的接口编号 int len = sock.size(); for (int i = 0; i < len; i++) if(V.find(sock[i]) == V.end()){ V[sock[i]] = ++vcnt; } //适配器连接,注意容量为无穷 cin >> k; for (int i = 0; i < k; i++) { string s1, s2; cin >> s1 >> s2; Cap[V[s1]][V[s2]] = INF; } //超级汇与接口连接 vcnt++; for (int i = 0; i < len; i++) if(can[sock[i][0]]) //注意只有房间有的接口才能与汇点连接 Cap[V[sock[i]]][vcnt] = 1; //设备与接口连接 map<string, string>::iterator iter; for (iter = dv.begin(); iter != dv.end(); iter++) { Cap[V[iter->first]][V[iter->second]] = 1; } //计算最大流 int left = m - EK(0, vcnt); cout << left << endl; //最后一个测试不输出换行 if (tests) cout << endl; } return 0; }
以上是关于uva753的主要内容,如果未能解决你的问题,请参考以下文章