UVA753:A Plug for UNIX
题意:给定一些插座和一些插头,还有一些单向接头,比如A->B
接头可以串联A->B->C->D
使得插座和插头匹配数目最大
题解:
首先接头可以用Floyd处理
这题可以转化为二分图的模型,就是直接连边,不做处理
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<map>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<queue>
#define MAXN 505
#define INF 0x7f7f7f7f
#define ll long long
#define P 203
using namespace std;
int n,m,e,N;
int V1[MAXN],V2[MAXN];
int G[MAXN<<][MAXN<<];
map<ll,int> mp;
ll Hash(string s){
ll ret=;
for(string::iterator it=s.begin();it!=s.end();it++){
ret=ret*P+(*it);
}
return ret;
}
struct Edge{
int from,to,cap,flow;
Edge(int u=,int v=,int c=,int f=){
from=u,to=v,cap=c,flow=f;
}
};
struct Dinic{
int n,m,s,t;
vector<Edge> edges;
vector<int> G[MAXN];
int b[MAXN];
int d[MAXN];
int cur[MAXN];
void init(int n,int s,int t){
this->n=n;
this->s=s,this->t=t;
edges.clear();
for(int i=;i<=n;i++){
G[i].clear();
}
}
void AddEdge(int x,int y,int cap){
edges.push_back(Edge(x,y,cap,));
edges.push_back(Edge(y,x,,));
m=edges.size();
G[x].push_back(m-);
G[y].push_back(m-);
}
bool BFS(){
memset(b,,sizeof(b));
queue<int> q;
d[s]=;
q.push(s);
b[s]=;
while(!q.empty()){
int x=q.front();q.pop();
for(int i=;i<G[x].size();i++){
Edge& e=edges[G[x][i]];
if(e.cap>e.flow&&!b[e.to]){
d[e.to]=d[x]+;
q.push(e.to);
b[e.to]=;
}
}
}
return b[t];
}
int dfs(int x,int a){
if(x==t||!a)return a;
int flow=,f;
for(int& i=cur[x];i<G[x].size();i++){
Edge& e=edges[G[x][i]];
if(d[e.to]==d[x]+&&(f=dfs(e.to,min(a,e.cap-e.flow)))>){
edges[G[x][i]].flow+=f;
edges[G[x][i]^].flow-=f;
flow+=f;
a-=f;
if(!a){
break;
}
}
}
return flow;
}
int Maxflow(){
int flow=;
while(BFS()){
memset(cur,,sizeof(cur));
flow+=dfs(s,INF);
}
return flow;
}
}D;
void init(){
memset(G,,sizeof(G));
mp.clear();
N=;
ll h;
string t1,t2;
scanf("%d",&n);
for(int i=;i<=n;i++){
cin>>t1;
h=Hash(t1);
if(mp.count(h)){
V1[i]=mp[h];
}
else{
N++;
mp[h]=N;
V1[i]=N;
}
}
scanf("%d",&m);
for(int i=;i<=m;i++){
cin>>t2>>t1;
h=Hash(t1);
if(mp.count(h)){
V2[i]=mp[h];
}
else{
N++;
mp[h]=N;
V2[i]=N;
}
}
scanf("%d",&e);
for(int i=;i<=e;i++){
cin>>t1>>t2;
int c1,c2;
h=Hash(t1);
if(mp.count(h)){
c1=mp[h];
}
else{
N++;
mp[h]=N;
c1=N;
}
h=Hash(t2);
if(mp.count(h)){
c2=mp[h];
}
else{
N++;
mp[h]=N;
c2=N;
}
G[c1][c2]=;
}
for(int i=;i<=n;i++){
G[i][i]=;
}
for(int k=;k<=N;k++){
for(int i=;i<=N;i++){
for(int j=;j<=N;j++){
G[i][j]|=(G[i][k]&G[k][j]);
}
}
}
}
void solve(){
D.init(n,,n+m+);
for(int i=;i<=m;i++){
for(int j=;j<=n;j++){
if(G[V2[i]][V1[j]]){
D.AddEdge(i,j+m,);
}
}
}
for(int i=;i<=m;i++){
D.AddEdge(,i,);
}
for(int j=;j<=n;j++){
D.AddEdge(j+m,n+m+,);
}
printf("%d\n",m-D.Maxflow());
}
int main()
{
// freopen("data.in","r",stdin);
// freopen("my.out","w",stdout);
int T;
scanf("%d",&T);
while(T--){
init();
solve();
if(T){
printf("\n");
}
}
return ;
}
二分图匹配
也可以把相同类型的压在一起处理,
源点到某类型插头的容量就是该类型的数目,汇点同理
如果相连的话建一条长度为INF的边,
然后跑一遍最大流即可
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<map>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<queue>
#define MAXN 505
#define INF 0x7f7f7f7f
#define ll long long
#define P 203
using namespace std;
int n,m,e,N;
int V1[MAXN],V2[MAXN];
int b1[MAXN],b2[MAXN];
int cnt1,cnt2;
int G[MAXN<<][MAXN<<];
map<string,int> mp;
struct Edge{
int from,to,cap,flow;
Edge(int u=,int v=,int c=,int f=){
from=u,to=v,cap=c,flow=f;
}
};
struct Dinic{
int n,m,s,t;
vector<Edge> edges;
vector<int> G[MAXN];
int b[MAXN];
int d[MAXN];
int cur[MAXN];
void init(int n,int s,int t){
this->n=n;
this->s=s,this->t=t;
edges.clear();
for(int i=;i<=n;i++){
G[i].clear();
}
}
void AddEdge(int x,int y,int cap){
edges.push_back(Edge(x,y,cap,));
edges.push_back(Edge(y,x,,));
m=edges.size();
G[x].push_back(m-);
G[y].push_back(m-);
}
bool BFS(){
memset(b,,sizeof(b));
queue<int> q;
d[s]=;
q.push(s);
b[s]=;
while(!q.empty()){
int x=q.front();q.pop();
for(int i=;i<G[x].size();i++){
Edge& e=edges[G[x][i]];
if(e.cap>e.flow&&!b[e.to]){
d[e.to]=d[x]+;
q.push(e.to);
b[e.to]=;
}
}
}
return b[t];
}
int dfs(int x,int a){
if(x==t||!a)return a;
int flow=,f;
for(int& i=cur[x];i<G[x].size();i++){
Edge& e=edges[G[x][i]];
if(d[e.to]==d[x]+&&(f=dfs(e.to,min(a,e.cap-e.flow)))>){
edges[G[x][i]].flow+=f;
edges[G[x][i]^].flow-=f;
flow+=f;
a-=f;
if(!a){
break;
}
}
}
return flow;
}
int Maxflow(){
int flow=;
while(BFS()){
memset(cur,,sizeof(cur));
flow+=dfs(s,INF);
}
return flow;
}
}D;
void init(){
memset(G,,sizeof(G));
memset(b1,,sizeof(b1));
memset(b2,,sizeof(b2));
cnt1=cnt2=;
mp.clear();
N=;
string t1,t2;
scanf("%d",&n);
for(int i=;i<=n;i++){
cin>>t1;
if(mp.count(t1)){
V1[i]=mp[t1];
}
else{
N++;
mp[t1]=N;
V1[i]=N;
}
}
scanf("%d",&m);
for(int i=;i<=m;i++){
cin>>t2>>t1;
if(mp.count(t1)){
V2[i]=mp[t1];
}
else{
N++;
mp[t1]=N;
V2[i]=N;
}
}
scanf("%d",&e);
for(int i=;i<=e;i++){
cin>>t1>>t2;
int c1,c2;
if(mp.count(t1)){
c1=mp[t1];
}
else{
N++;
mp[t1]=N;
c1=N;
}
if(mp.count(t2)){
c2=mp[t2];
}
else{
N++;
mp[t2]=N;
c2=N;
}
G[c1][c2]=;
}
for(int i=;i<=n;i++){
G[i][i]=;
}
for(int k=;k<=N;k++){
for(int i=;i<=N;i++){
for(int j=;j<=N;j++){
G[i][j]|=(G[i][k]&G[k][j]);
}
}
}
for(int i=;i<=n;i++){
if(!b1[V1[i]]){
cnt1++;
}
b1[V1[i]]++;
}
for(int i=;i<=m;i++){
if(!b2[V2[i]]){
cnt2++;
}
b2[V2[i]]++;
}
}
void solve(){
D.init(n,,cnt1+cnt2+);
int t1=,t2=cnt1;
for(int i=;i<=N;i++){
if(b2[i]) t2++;
else continue;
t1=;
for(int j=;j<=N;j++){
if(b1[j]){
t1++;
if(G[i][j]){
D.AddEdge(t1,t2,INF);
}
}
}
}
t1=;
for(int i=;i<=N;i++){
if(b1[i]){
t1++;
D.AddEdge(,t1,b1[i]);
}
}
t2=;
for(int j=;j<=N;j++){
if(b2[j]){
t2++;
D.AddEdge(t2+cnt1,cnt1+cnt2+,b2[j]);
}
}
printf("%d\n",m-D.Maxflow());
}
int main()
{
// freopen("data.in","r",stdin);
// freopen("my.out","w",stdout);
int T;
scanf("%d",&T);
while(T--){
init();
solve();
if(T){
printf("\n");
}
}
return ;
}
压点最大流
UVA753:A Plug for UNIX的更多相关文章
- 【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 ...
- 【uva753/poj1087/hdu1526-A Plug for UNIX】最大流
题意:给定n个插座,m个插头,k个转换器(x,y),转换器可以让插头x转成插头y.问最少有多少个插头被剩下. 题解: 最大流或者二分图匹配.然而我不知道怎么打二分图匹配..打了最大流.这题字符串比较坑 ...
- uva753 A Plug for UNIX 网络流最大流
C - A Plug for UNIX You are in charge of setting up the press room for the inaugural meeting of t ...
- A Plug for UNIX 分类: POJ 图论 函数 2015-08-10 14:18 2人阅读 评论(0) 收藏
A Plug for UNIX Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14786 Accepted: 4994 Desc ...
- UVa753/POJ1087_A Plug for UNIX(网络流最大流)(小白书图论专题)
解题报告 题意: n个插头m个设备k种转换器.求有多少设备无法插入. 思路: 定义源点和汇点,源点和设备相连,容量为1. 汇点和插头相连,容量也为1. 插头和设备相连,容量也为1. 可转换插头相连,容 ...
- poj 1087 C - A Plug for UNIX 网络流最大流
C - A Plug for UNIXTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contes ...
- UVA 753 - A Plug for UNIX(网络流)
A Plug for UNIX You are in charge of setting up the press room for the inaugural meeting of the U ...
- POJ1087 A Plug for UNIX 【最大流】
A Plug for UNIX Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 13855 Accepted: 4635 ...
- 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 ...
随机推荐
- 高级软件工程2017第6次作业——团队项目:Alpha阶段综合报告
1.版本测试报告 1.1在测试过程中总共发现了多少Bug?每个类别的Bug分别为多少个? Bug分类 Bug内容 Fixed 编辑博文时改变文字格式会刷新界面 Can't reproduced 无 N ...
- 关于GPUImage的导入
对于GPUImage的使用方面,GitHub上已经非常详细了,就不一一赘述了,但是对于项目的导入来说,最好的方式是 1.下载GPUImage并解压 2.打开压缩包后如图 3.打开终端,cd到此目录 4 ...
- openlayers调用瓦片地图分析
网上有诸多资料介绍openlayers如何调用百度地图或者是天地图等常见互联网地图,本文作者使用的是不是常见的互联网瓦片,现将调用过程进行整理与大家分享. 首先,openlayers就不赘述了(官网: ...
- JAVA_SE基础——13.选择结构语句
if选择结构 语法: if(条件){ 代码块 } public class Test{ public static void main(String[] args){ int a = 5; if(a ...
- C语言使用vs2013进行编辑
由于vs2013是微软开发的产品所以在windows平台下无限兼容windows所有虽然比较大,但是还是比较值得 但是在运行C程序的遇到问题就是控制台一闪而过通过ctrl+F5执行也是不管用: #in ...
- ( 转 ) 聊一聊C#的Equals()和GetHashCode()方法
聊一聊C#的Equals()和GetHashCode()方法 博客创建一年多,还是第一次写博文,有什么不对的地方还请多多指教. 关于这次写的内容可以说是老生长谈,百度一搜一大堆.大神可自行绕路. ...
- ELK学习总结(2-6)elk的mapping
1.什么是映射 映射:创建索引的时候,预先定义字段的类型及相关属性 作用:这样会让索引建立的更加细致和完善,如:是否存储.使用何种分析器.重要级别 分类:静态映射和动态映射 2.字段类型:string ...
- 记录安装centos6.5的几个要紧步骤
1.安装新系统 因为是服务器,不是普通电脑,貌似对usb支持不好,所以用的光盘安装. centos 6.5 64位 2.跳过测试 3.服务器语言 选择english,键盘是english.US 4.选 ...
- vue中的数据监听以及数据交互
现在我们来看一下vue中的数据监听事件$watch, js代码: new Vue({ el:"#div", data:{ arr:[,,] } }).$watch("ar ...
- linux系统环境与文件权限
默认有6个命令交互通道和一个图形界面交互通道,默认进入到的是图形界面通道 命令交互模式切换:ctrl+alt+f1---f6 图形交互界面 ctrl+alt+f7 1.图形界面交互模式 - termi ...