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 ...
随机推荐
- C语言最后一次博客作业
1.当初你是如何做出选择计算机专业的决定的? 一开始选专业的时候,说实话我很纠结也很迷茫,对我来说,中学时代,似乎就只要考好试,做好题就可以了,对于未来想要做啥并没有那么多的规划和想法,偶尔跟基友畅聊 ...
- Django 基本设置
建立django目录,为了独立区分app和主站的关系,需要把app完全和主站分离 app/views.py from django.shortcuts import render from djang ...
- iOS开发-OC数据类型
以下是OC中的实例,Swift部分不适用 iOS中的注释 // 单行注释 // 注释对代码起到解释说明的作用,注释是给程序员看的,不参与程序运行 /* 多行注释 Xcode快捷键 全选 cm ...
- java实现红包的分配算法
个人推测,微信红包在发出的时候已经分配好金额.比如一个10元的红包发给甲乙丙三个人,其实在红包发出去的时候,已经确定了第一个会领取多少,第二个会领取多少金额. 而不是在领取的时候才计算的.下面贴出实现 ...
- JAVA_SE基础——9.基本数据类型间的转换
前面我已经教会大家基本的数据类型进行了介绍, 然后这篇文章,我来介绍下,基本数据类型的转换. Java中有两种类型转换形式,分别是自动类型转换和强制类型转换. Step1.自动类型转换. 自动类型 ...
- linux的链接工具secure设置字体大小和颜色
- Service Worker和HTTP缓存
很多人,包括我自己,初看Service Worker多一个Cache Storage的时候,就感觉跟HTTP长缓存没什么区别. 例如大家讲的最多的Service Worker能让网页离线使用,但熟悉H ...
- 记录Yii2代码调试中出现的两个问题(截图展示)
1.代码会中断执行,不提示错误信息,是由于substr函数第一个参数为数组造成的 2. 谷歌浏览器调试异步调用接口时出现的错误,需在接口返回处进行断点调试 这两个错误比较隐蔽,调试代码时必须认真仔细
- 分贝块---dBblock
分贝,用英语来表达的话,是decibel,是量度两个相同单位之数量比例的计量单位,主要用于度量声音强度,常用dB表示. 块,block,在百度百科中,指数据库中的最小存储和处理单位,包含块本身的头信息 ...
- python入门(6)输入和输出
python入门(6)输入和输出 输出 >>> print 'hello, world' >>> print 'The quick brown fox', 'jum ...