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 ...
随机推荐
- 用python实现简单购物车功能
all_asset = 0 i1 = input("请输入总资产:") all_asset = int(i1) goods = [ {'name':'电脑','price':199 ...
- 关于jvm的OutOfMemory:PermGen space异常的解决
在做网校的时候,经常会在控制台会报出方法区的内存溢出,在网上找的方法,无非都是在tomcat的bin/catalina.bat文件中 设置jvm的堆的大小和方法区的大小,但是通过eclipse启动to ...
- JAVA_SE基础——45.基本类型变量.值交换[独家深入解析]
需求:定义一个函数交换两个基本类型变量的值. 相信看过我前面的文章的同学都应该看的懂我以下的代码: class Demo2 { public static void main(String[] arg ...
- 泛型的 typeof
static void Main(string[] args) { TestTypeOf<string>(); Console.ReadKey(); } static void TestT ...
- 详解Ajax请求(二)——异步请求原理的分析
在上一文章里,我们分析了同步请求的原理.当浏览器向服务器发送同步请求时,服务处理同步请求的过程中,浏览器会处于等待的状态,服务器处理完请求把数据响应给浏览器并覆盖浏览器内存中原有的数据,浏览器重新加载 ...
- SpringMVC(三):@RequestMapping中的URL中设定通配符,可以使用@PathVariable映射URL绑定的占位符
1)带占位符的URL是Spring3.0新增的功能,该功能在SpringMVC向REST目标挺进发展过程中具有里程碑的意义. 2)通过@PathVariable可以将URL中占位符参数绑定到控制器处理 ...
- Java-Maven(六):Eclipse中Maven插件的命令操作
之前几个章节学习了maven的概念,及maven插件安装后如何创建工程,那么maven工程中是如何使用maven命令呢?本章节将会学习这个话题. 在pom.xml中配置maven命令插件 如果向在ma ...
- POJ-1700 Crossing River---过河问题(贪心)
题目链接: https://vjudge.net/problem/POJ-1700 题目大意: 有N个人要渡河,但是只有一艘船,船上每次最多只能载两个人,渡河的速度由两个人中较慢的那个决定,小船来回载 ...
- logging的使用方法
logging的使用方法 1,简单使用方法 >>> import logging >>> logging.warning('this is a warning') ...
- [转]pycharm常用快捷键及设置
PyCharm3.0默认快捷键(翻译的) PyCharm Default Keymap 1.编辑(Editing) Ctrl + Space 基本的代码完成(类.方法.属性)Ctrl + Alt ...