【最大流 && 映射】POJ - 1087 A Plug for UNIX
2017-09-25 19:57
417 查看
Problem Description
输入n代表插排上有n个插口。接下来输入n行,每行输入一个字符串代表属于什么类型插口。
输入nn代表有nn个电器。接下来nn行,每行输入两个字符串,代表第一个字符串这个电器 可以 插到第二个字符串这种插口。
输入m代表有m种转换器,转换器个数不限,接下来输入m行,每行输入两个字符串,代表可以将第二个字符串的插口转换为第一个字符串这种插口类型。
思路:
核心就是读懂题目,问了学长题目什么意思才懂的。然后把字符串都映射成点,建图,求最大流就好了。答案是nn-最大流。
输入n代表插排上有n个插口。接下来输入n行,每行输入一个字符串代表属于什么类型插口。
输入nn代表有nn个电器。接下来nn行,每行输入两个字符串,代表第一个字符串这个电器 可以 插到第二个字符串这种插口。
输入m代表有m种转换器,转换器个数不限,接下来输入m行,每行输入两个字符串,代表可以将第二个字符串的插口转换为第一个字符串这种插口类型。
思路:
核心就是读懂题目,问了学长题目什么意思才懂的。然后把字符串都映射成点,建图,求最大流就好了。答案是nn-最大流。
#include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<map> #include<iostream> using namespace std; struct node { int to, w, next; }; node Map[50000]; int head[500], vis[500], cnt; void add(int u, int v, int w)//前向星存图 { Map[cnt].to = v; Map[cnt].w = w; Map[cnt].next = head[u]; head[u] = cnt++; Map[cnt].to = u; Map[cnt].w = 0; Map[cnt].next = head[v]; head[v] = cnt++; } int dfs(int s, int e, int f)//找增广路,找到返回限制流量,找不到返回0 { vis[s] = 1; if(s == e) return f; for(int i = head[s]; ~i; i = Map[i].next) { int to = Map[i].to, &w = Map[i].w; if(!vis[to] && w) { int d = dfs(to, e, min(f, w)); if(d > 0) { w -= d; Map[i^1].w += d; return d; } } } return 0; } int ek(int s, int e)//最大流 { int Max_flow = 0, flow = 0; for(;;) { memset(vis, 0, sizeof(vis)); flow = dfs(s, e, 0x3f3f3f3f); if(flow == 0) break; Max_flow += flow; } return Max_flow; } int main() { int n, i, m, nn; string s, str; while(~scanf("%d", &n)) { cnt = 0; int top = 1; memset(head, -1, sizeof(head)); map<string, int> q; map<string, int>::iterator it; for(i = 1; i <= n; i++) { cin >> s; q[s] = top++; } scanf("%d", &nn); for(i = 1; i <= nn; i++) { cin >> str >> s; if(!q.count(str)) q[str] = top++; if(!q.count(s)) q[s] = top++; add(q[str], q[s], 1);//用电器和插口类型建边,流量为1 add(0, q[str], 1);//超级源点和用电器建边,流量为1 } scanf("%d", &m); while(m--) { cin >> str >> s;//转换器可以将s类型的插口变为str类型 if(!q.count(str)) q[str] = top++; if(!q.count(s)) q[s] = top++; add(q[str], q[s], 0x3f3f3f3f);//str类型插口和s类型插口建边,流量为无穷(无穷多个) } for(i = 1; i <= n; i++) { add(i, i+top-1, 1);//插口和插口建边,流量为1,毕竟插口只有一个 add(i+top-1, n+top, 1);//插口和超级汇点建边流量为1 } printf("%d\n", nn - ek(0, n + top)); } return 0; }
相关文章推荐
- poj1087 A Plug for UNIX & poj1459 Power Network (最大流)
- POJ1087 A Plug for UNIX(网络流,最大流,EK算法)
- POJ1087 A Plug for UNIX 二分图最大匹配
- POJ1087 A Plug for UNIX 【最大流】
- POJ 1087 A Plug for UNIX (最大流)
- poj 1087 A Plug for UNIX(最大流)
- POJ 1087 A Plug for UNIX(网络流—最大流(最大二分匹配))
- POJ 1087 A Plug for UNIX (最大流+多源多汇)
- poj 1087 A Plug for UNIX(最大流)
- POJ 1087 A Plug for UNIX 最大流
- A Plug for UNIX POJ - 1087 最大流 思维建图
- 【最大流】POJ-1087 A Plug for UNIX
- POJ 1087 A Plug for UNIX【二分图最大匹配】
- POJ 1087 A Plug for UNIX 网络流最大流
- POJ 1087 A Plug for UNIX 会议室插座问题 构图+最大流
- POJ 1087 A Plug for UNIX【最大流】
- POJ 1087 A Plug for UNIX(最大流dinic)
- POJ 1087 A Plug for UNIX 最大流
- poj 1087 A Plug for UNIX 【最大流】
- POJ 1087 A Plug for UNIX (最大流,EK算法)