ZOJ 1157A Plug for UNIX(二分图最大匹配)

来源:互联网 发布:网络短信诈骗的论文 编辑:程序博客网 时间:2024/05/22 13:55

建图比较繁琐.

对于每一个adapter(a b) 连接 a -> b一条有向边.就是能把插在a的插座上的电器插到b插座上

然后对每一个插座i进行DFS,把能够到达的插座j标号,意思就是能把插在j的插座上的电器 插到i上.

最后匈牙利算法.

#include <iostream>#include <cstdio>#include <memory.h>#include <vector>#include <map>#include <string>using namespace std;const int maxn = 600;map<string, int> sToNum;map<int,int> g2;vector<int> g1[maxn];map<int,map<int,int> > ada;bool vis[maxn];int fa[maxn],n, m, k, idx;char buf1[maxn], buf2[maxn];bool fg[maxn][maxn];void dfs(int u, int o){vis[u] = 1;for (int i = 0; i < g1[u].size(); ++i){if(!vis[g1[u][i]]){dfs(g1[u][i],o);ada[o][g1[u][i]] =1;}}}bool dfs2(int u){for (int v = 1; v <= idx; ++v){if(fg[u][v] && !vis[v]){vis[v] = 1;if (fa[v] ==0 || dfs2(fa[v])){fa[v] = u;return true;}}}return false;}int hungary(){int ans = 0;memset(fa, 0, sizeof(fa));for (int i = 1; i <= n; ++i){memset(vis, 0, sizeof(vis));if(dfs2(i)){ans++;}}return ans;}void init(){memset(fg, 0, sizeof(fg));sToNum.clear();ada.clear();g2.clear();for (int i = 0 ; i < maxn; ++i){g1[i].clear();}}int main(){int T;scanf("%d", &T);while (T--){init();scanf("%d", &n);int id = 1;for (int i = 0; i < n; ++i){scanf("%s", buf1);sToNum[buf1] = id++;}scanf("%d", &m);for (int i = 0; i < m; ++i){scanf("%s %s", buf1, buf2);int id1 = sToNum[buf1], id2 = sToNum[buf2];if(id1 == 0){id1 = sToNum[buf1] = id++;}if(id2 == 0){id2 = sToNum[buf2] = id++;}g2[id1] = id2;}scanf("%d", &k);for (int i = 0; i < k; ++i){scanf("%s %s", buf1, buf2);int id1 = sToNum[buf1], id2 = sToNum[buf2];if(id1 == 0){id1 = sToNum[buf1] = id++;}if(id2 == 0){id2 = sToNum[buf2] = id++;}g1[id1].push_back(id2); //适配器a -> b 表示可以把 用a的插头的电器插在b插座上.}for (int i = 1; i <= id; ++i){memset(vis, 0, sizeof(vis));dfs(i,i);}map<int,int>::iterator it = g2.begin();for (;it != g2.end(); ++it){fg[it->first][it->second] = fg[it->second][it->first] =1;map<int,int>::iterator it2 = ada[it->second].begin();for (; it2 != ada[it->second].end(); ++it2){fg[it->first][it2->first] = fg[it2->first][it->first] =1;}}idx = id;printf("%d\n", m - hungary());if(T)printf("\n");}return 0;}


原创粉丝点击