POJ--1087--A Plug for UNIX【Dinic】网络最大流

链接:http://poj.org/problem?id=1087

题意:提供n种插座,每种插座只有一个,有m个设备需要使用插座,告诉你设备名称以及使用的插座类型,有k种转换器,可以把某种插座类型转为另一种,可以嵌套使用,比如有设备需使用第4种插座,现在只有第一种插座,但是有两个转换器,1→3和3→4,则通过这两个转换器设备可以充电。每种转换器有无数个。现告诉你相应信息,求至少有多少个设备无法使用插座。

网络最大流单源点单汇点,是一道基础题,图建好就能套模板了。关键是图怎么建。

还是自己设一个源点和一个汇点,源点出发到每种设备各有一条路径容量为1,现在已有的插座种类到汇点各有一条路径容量为1,反过来也行,最大流的值不会因为这个而改变。每种设备各有一个需要使用的插座类型,把这些设备和各自需要的插座连一条路径,容量为1。对于转换器,如果把a转为b,就在a和b之间连一条路径,容量为正无穷,图就建好了。

如果说的不够清楚,看了这个图也能一目了然,这是根据题目样例建的图:

#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 50100
#define eps 1e-7
#define INF 0x7FFFFFFF
#define seed 131
#define mod 1000000007
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

struct node{
    int u,w,next;
}edge[10100];
int head[210],vis[210],dist[210];
int n,m,k,src,sink,cnt;
int num1,num2;
map<string,int>mp;
void add_edge(int a,int b,int c){
    edge[cnt].u = b;
    edge[cnt].w = c;
    edge[cnt].next = head[a];
    head[a] = cnt++;
}
void bfs(){
    int i,j;
    memset(dist,0,sizeof(dist));
    queue<int>q;
    vis[src] = 1;
    q.push(src);
    while(!q.empty()){
        int tt = q.front();
        q.pop();
        for(i=head[tt];i!=-1;i=edge[i].next){
            if(!vis[edge[i].u]&&edge[i].w){
                dist[edge[i].u] = dist[tt] + 1;
                vis[edge[i].u] = 1;
                q.push(edge[i].u);
            }
        }
    }
}
int dfs(int u,int delta){
    int i,j;
    if(u==sink) return delta;
    int ret = 0;
    for(i=head[u];i!=-1;i=edge[i].next){
        if(edge[i].w&&dist[edge[i].u]==dist[u]+1){
            int dd = dfs(edge[i].u,min(delta,edge[i].w));
            edge[i].w -= dd;
            edge[i^1].w += dd;
            delta -= dd;
            ret += dd;
        }
    }
    return ret;
}
int maxflow(){
    int ret = 0;
    while(1){
        memset(vis,0,sizeof(vis));
        bfs();
        if(vis[sink]==0)    break;
        ret += dfs(src,INF);
    }
    return ret;
}
int main(){
    int i,j;
    string str1,str2;
    memset(head,-1,sizeof(head));
    num1 = 1;
    num2 = 101;
    cnt = 0;
    src = 0;
    sink = 205;
    scanf("%d",&n);
    for(i=0;i<n;i++){
        cin>>str1;
        mp[str1] = num1++;
        add_edge(mp[str1],sink,1);
        add_edge(sink,mp[str1],0);
    }
    scanf("%d",&m);
    for(i=0;i<m;i++){
        cin>>str1>>str2;
        mp[str1] = num2++;
        if(!mp[str2])   mp[str2] = num1++;
        add_edge(mp[str1],mp[str2],1);
        add_edge(mp[str2],mp[str1],0);
        add_edge(src,mp[str1],1);
        add_edge(mp[str1],src,0);
    }
    scanf("%d",&k);
    for(i=0;i<k;i++){
        cin>>str1>>str2;
        add_edge(mp[str1],mp[str2],INF);
        add_edge(mp[str2],mp[str1],0);
    }
    int ans = maxflow();
    printf("%d\n",m-ans);
    return 0;
}

POJ--1087--A Plug for UNIX【Dinic】网络最大流,布布扣,bubuko.com

时间: 2024-10-23 16:07:27

POJ--1087--A Plug for UNIX【Dinic】网络最大流的相关文章

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

POJ 1087 A Plug for UNIX 链接:http://poj.org/problem?id=1087 题意:有n(1≤n≤100)个插座,每个插座用一个数字字母式字符串描述(至多有24 个字符).有m(1≤m≤100)个设备,每个设备有名称,以及它使用的插头的名称:插头的名称跟它所使用的插座的名称是一样的:设备名称是一个至多包含24 个字母数字式字符的字符串:任何两个设备的名称都不同:有k(1≤k≤100)个转换器,每个转换器能将插座转换成插头. 样例: 4 A B C D 5

POJ 1087 A Plug for UNIX(网络流之最大流)

题目地址:POJ 1087 不知道是谁把这题化为了二分最大匹配的专题里..于是也没多想就按照二分图的模型来建的(虽然当时觉得有点不大对...).后来发现二分最大匹配显然不行..有权值..直接来个最大流多方便..然后一直WA..后来仔细想了想..这根本就不能建二分图啊....这题跟二分图一点关系都没有.... 这题的建图思路是让源点与每一个设备的插座类型连边,让汇点与每一个插座连边.然后用floyd判断该设备能否通过转换转换成可以插的插座上.只要可以转换成的就连边,权值为INF.然后求一次最大流,

POJ 1087 A Plug for UNIX 会议室插座问题 构图+最大流

题目链接:POJ 1087 A Plug for UNIX A Plug for UNIX Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13809   Accepted: 4623 Description You are in charge of setting up the press room for the inaugural meeting of the United Nations Internet eXec

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

A Plug for UNIX Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14862   Accepted: 5026 Description You are in charge of setting up the press room for the inaugural meeting of the United Nations Internet eXecutive (UNIX), which has an int

POJ 1087 A Plug for UNIX (最大流)

A Plug for UNIX Time Limit: 1000MS   Memory Limit: 65536K       Description You are in charge of setting up the press room for the inaugural meeting of the United Nations Internet eXecutive (UNIX), which has an international mandate to make the free

POJ 1087 A Plug for UNIX(最大流dinic)

Description You are in charge of setting up the press room for the inaugural meeting of the United Nations Internet eXecutive (UNIX), which has an international mandate to make the free flow of information and ideas on the Internet as cumbersome and

poj 1087 A Plug for UNIX 【最大流】

题目连接:http://poj.org/problem?id=1087 题意: n种插座 ,m个电器,f组(x,y)表示插座x可以替换插座y,问你最多能给几个电器充电. 解法:起点向插座建边,容量1,电器向汇点建边,容量1,插座向电器建边,容量1,可以替换的插座间建边,容量无穷大.然后套板子...求最大流. 代码: #include <stdio.h> #include <ctime> #include <math.h> #include <limits.h>

POJ 1087 —— A Plug for UNIX

原题:http://poj.org/problem?id=1087 题意:n个插座,m个电器及其对应的插座,k种转化器,转换器(u,v)表示可以把原本需要u插座的电器转接到v插座上,问最少有多少设备没有插座用,每种转换器数量不限;: #include<cstdio> #include<cstring> #include<string> #include<queue> #include<vector> #include<map> #in

POJ 1087 A Plug for UNIX

网络最大流水题 #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<vector> #include<queue> #include<map> #include<algorithm> using namespace std; const int maxn=1000+10; const int INF=0x7FF

POJ - 1087 A Plug for UNIX (网络流)

原题链接 题意: 给定 N 个不同类型插座,每个插座只能插一个相对应的设备 : 现有 M 个人,给出每个人名字和设备的插头类型,然后给定 K 种转换器,每种转换器的数量都是无限的,每种转化器描述为: 插座类型,插头类型: 现在问至少有多少个人的设备无法插入. 思路: 一个典型的最大流问题,设定超级源点 S , 超级汇点 T ,将每种插座与 S 相连,流量为1:将所有人的插头类型统计一下,并记录数量,然后将其与汇点相连,流量为每种插头的数量: 记录所有的转换器,用 Floyd 算出 每种插头最终可