网络流,关键在建图

建图思路在代码里

/*
最大流SAP
邻接表
思路:基本源于FF方法,给每个顶点设定层次标号,和允许弧。
优化:
1、当前弧优化(重要)。
1、每找到以条增广路回退到断点(常数优化)。
2、层次出现断层,无法得到新流(重要)。
时间复杂度(m*n^2)
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#define ms(a,b) memset(a,b,sizeof a)
using namespace std;
const int INF = ;
struct node {
int v, c, next;
} edge[INF*INF * ];
int pHead[INF*INF], SS, ST, nCnt;
void addEdge (int u, int v, int c) {
edge[++nCnt].v = v; edge[nCnt].c = c, edge[nCnt].next = pHead[u]; pHead[u] = nCnt;
edge[++nCnt].v = u; edge[nCnt].c = , edge[nCnt].next = pHead[v]; pHead[v] = nCnt;
}
int SAP (int pStart, int pEnd, int N) {
int numh[INF], h[INF], curEdge[INF], pre[INF];
int cur_flow, flow_ans = , u, neck, i, tmp;
ms (h, ); ms (numh, ); ms (pre, -);
for (i = ; i <= N; i++) curEdge[i] = pHead[i];
numh[] = N;
u = pStart;
while (h[pStart] <= N) {
if (u == pEnd) {
cur_flow = 1e9;
for (i = pStart; i != pEnd; i = edge[curEdge[i]].v)
if (cur_flow > edge[curEdge[i]].c) neck = i, cur_flow = edge[curEdge[i]].c;
for (i = pStart; i != pEnd; i = edge[curEdge[i]].v) {
tmp = curEdge[i];
edge[tmp].c -= cur_flow, edge[tmp ^ ].c += cur_flow;
}
flow_ans += cur_flow;
u = neck;
}
for ( i = curEdge[u]; i != ; i = edge[i].next)
if (edge[i].c && h[u] == h[edge[i].v] + ) break;
if (i != ) {
curEdge[u] = i, pre[edge[i].v] = u;
u = edge[i].v;
}
else {
if ( == --numh[h[u]]) continue;
curEdge[u] = pHead[u];
for (tmp = N, i = pHead[u]; i != ; i = edge[i].next)
if (edge[i].c) tmp = min (tmp, h[edge[i].v]);
h[u] = tmp + ;
++numh[h[u]];
if (u != pStart) u = pre[u];
}
}
return flow_ans;
}
/*
poj1087 最大流
建图:
每个种插座和为一个节点,添加源点和汇点
源点到每个存在的插座连一条容量为插座数量的边
统计需要每种插座的数量,作为插座到汇点边的容量
如果有转换器A->B,AB连接一条容量无限的边
*/
int k, m, n, tol;
int sum[INF], need[INF];
map<string, int> mat;
string s,ss;
int main() {
/*
前向星存边,表头在pHead[],初始化nCnt=1
SS,ST分别为源点和汇点
*/
nCnt = ;
cin >> n;
for (int i = ; i <= n; i++) {
cin >> s;
if (mat.find (s) == mat.end() ) mat[s] = ++tol;
sum[tol]++;
}
cin >> m;
for (int i = ; i <= m; i++) {
cin >> ss >> s;
if (mat.find (s) == mat.end() ) mat[s] = ++tol;
need[mat[s]]++;
}
cin>>k;
for (int i=;i<=k;i++){
cin>>ss>>s;
if (mat.find (s) == mat.end() ) mat[s] = ++tol;
if (mat.find (ss) == mat.end() ) mat[ss] = ++tol;
int u=mat[s],v=mat[ss];
addEdge(u,v,);
}
SS=tol+,ST=tol+;
for(int i=;i<=tol;i++){
addEdge(SS,i,sum[i]);
addEdge(i,ST,need[i]);
}
int ans=SAP(SS,ST,ST);
cout<<m-ans<<endl;
return ;
}

poj 1087.A Plug for UNIX (最大流)的更多相关文章

  1. POJ 1087 A Plug for UNIX / HDU 1526 A Plug for UNIX / ZOJ 1157 A Plug for UNIX / UVA 753 A Plug for UNIX / UVAlive 5418 A Plug for UNIX / SCU 1671 A Plug for UNIX (网络流)

    POJ 1087 A Plug for UNIX / HDU 1526 A Plug for UNIX / ZOJ 1157 A Plug for UNIX / UVA 753 A Plug for ...

  2. poj 1087 A Plug for UNIX(字符串编号建图)

    A Plug for UNIX Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14862   Accepted: 5026 ...

  3. poj 1087 A Plug for UNIX 【最大流】

    题目连接:http://poj.org/problem? id=1087 题意: n种插座 ,m个电器,f组(x,y)表示插座x能够替换插座y,问你最多能给几个电器充电. 解法:起点向插座建边,容量1 ...

  4. POJ 1087 A Plug for UNIX (网络流,最大流)

    题面 You are in charge of setting up the press room for the inaugural meeting of the United Nations In ...

  5. kuangbin专题专题十一 网络流 POJ 1087 A Plug for UNIX

    题目链接:https://vjudge.net/problem/POJ-1087 题目:有n个插座,插座上只有一个插孔,有m个用电器,每个用电器都有插头,它们的插头可以一样, 有k个插孔转化器, a ...

  6. poj 1087 A Plug for UNIX

    题目描述:现在由你负责布置Internet联合组织首席执行官就职新闻发布会的会议室.由于会议室修建时被设计成容纳全世界各地的新闻记者,因此会议室提供了多种电源插座用以满足(会议室修建时期)各国不同插头 ...

  7. 【poj 1087 a plug for UNIX】

    在大米饼的帮助下,终于找到了大米饼程序中如同大米饼一般的错误! 考点在问题转化,然后就跑一个你喜欢的最大流算法(二分图可以啵?) 再来一个例子吧: [纯手绘大米饼图片] 其中有的边权是1,否则就是in ...

  8. hdu 1087 A Plug for UNIX 最大流

    题意:http://www.phpfans.net/article/htmls/201012/MzI1MDQw.html 1.在一个会议室里有n种插座,每种插座一个: 2.每个插座只能插一种以及一个电 ...

  9. 【poj1087/uva753】A Plug for UNIX(最大流)

    A Plug for UNIX   Description You are in charge of setting up the press room for the inaugural meeti ...

随机推荐

  1. 【转】java代码中实现android背景选择的selector-StateListDrawable的应用

    原文网址:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0924/1712.html 下面的代码应该很多人都熟悉: 1 2 3 ...

  2. 培训机构出来的iOS学员怎么了?

    事件回放 前几天在 iOS 开发群里看到有人贴了一个 v2ex 上的帖子(地址:https://www.v2ex.com/t/244437 ) ,大概说收到了 1000 多份某培训机构出来的学员简历. ...

  3. js 的 提交

    <script type="text/javascript"> function sub(){ if(document.form1.xingming.value==&q ...

  4. ubuntu错误解决。

    ubuntu中出现如下错误: W: Failed to fetch http://cn.archive.ubuntu.com/ubuntu/dists/precise-backports/main/i ...

  5. Java反射获取类和对象信息全解析

    反射可以解决在编译时无法预知对象和类是属于那个类的,要根据程序运行时的信息才能知道该对象和类的信息的问题. 在两个人协作开发时,你只要知道对方的类名就可以进行初步的开发了. 获取类对象 Class.f ...

  6. JavaEE学习笔记---数据库操作篇

    测试JDBC和SQLServer的插入操作,源码如下: import java.sql.Connection;import java.sql.DriverManager;import java.sql ...

  7. uva10829 L-Gap Substrings

    题意 给出一个长度为\(n(\leqslant 50000)\)的字符串,求形如\(\mathrm{UVU}\)形式的字串,其中\(\mathrm{V}\)的长度给定. 题解 枚举\(\mathrm{ ...

  8. sqlserver 增加表字段

    ALTER TABLE [ImportCompanys]ADD shortName nvarchar(500)ADD ID int identity (1,1)

  9. PPT扁平化手册 2

  10. Java序列化之Serializable

    Java的序列化流程如下: Java的反序列化流程如下: 注意:并不是所有类都需要进行序列化,主要原因有两个 1)安全问题.Java中有的类属于敏感类,此类的对象数据不便对外公开,而序列化的对象数据很 ...