poj 1087 A Plug for UNIX

题目链接:poj 1087

这道题,感觉考得是阅读理解啊,题目又臭又长。。。。

 

参考题意:https://blog.csdn.net/qq_38367681/article/details/81392291

题意:在一个会议室里有n种插座,每种插座一个,每个插座只能插一种以及一个电器(或者适配器),有m个电器,每个电器有一个插头需要插在相应一种插座上,不是所有电器都能在会议室找到相应插座,有k种适配器,每种适配器可以有无限多数量,每种适配器(a, b)可以把b类插座变为a类插座,问最后有多少个电器无法使用。

 

题解:参考链接:https://www.cnblogs.com/kuangbin/archive/2012/08/21/2649946.html


 

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<map>
#include<string>
#include<iostream>
using namespace std;

#define INF 0x3f3f3f3f
const int maxn=500;

int capacity[maxn][maxn]; ///存储值
int  flow[maxn];
int path[maxn],start,end;
int n; ///建模后的总结点

queue<int> myqueue;

int bfs()
{
    while(!myqueue.empty()) myqueue.pop();

    memset(path,-1,sizeof(path));

    path[start]=0;
    flow[start]=INF;

    myqueue.push(0);

    while(!myqueue.empty())
    {
        int t=myqueue.front();
        myqueue.pop();

        if(t==end) break;

        for(int i=0;i<=n;i++)
        {
            if(i!=start&&path[i]==-1&&capacity[t][i])
            {
                flow[i]=min(flow[t],capacity[t][i]);
                myqueue.push(i);
                path[i]=t;
            }
        }
    }

    if( path[end]==-1 ) return -1;
    return flow[end];
}

int Edmond_Karp()
{

    int max_flow=0;
    int step,now,pre;

    while((step=bfs())!=-1)
    {
        now=end;
        max_flow+=step;
        while(now!=start){
            pre=path[now];
            capacity[pre][now]-=step;
            capacity[now][pre]+=step;
            now=pre;
        }
    }
    return max_flow;
}

map<string,int> hash;
int main()
{
        cin.tie(0);
    ios::sync_with_stdio(0);

    string str1,str2;
    int N,M,K;

    while(~scanf("%d",&N))
    {
        hash.clear();

        memset(capacity,0,sizeof(capacity));

        start=0; ///源点
        end=1; ///汇点
        int tol=2;

        while(N--)
        {
            cin>>str1;
            hash[str1]=tol;
            capacity[0][tol]=1; ///建立源点与插座之间的边
            tol++;
        }

        scanf("%d",&M);
       for(int i=1;i<=M;i++)
        {
            cin>>str1>>str2;

            if(hash[str1]==0) hash[str1]=tol++;
            if(hash[str2]==0) hash[str2]=tol++;

            capacity[hash[str1]][end]=1;  ///建立用电器与汇点的边
            capacity[hash[str2]][hash[str1]]=1; ///建立插座(或者适配器)与用电器之间的边
        }

        scanf("%d",&K);
        while(K--)
        {
            cin>>str1>>str2;

            if(hash[str1]==0) hash[str1]=tol++;
            if(hash[str2]==0) hash[str2]=tol++;
            capacity[hash[str2]][hash[str1]]=INF; ///题目say了,适配器是无穷无尽的,故把插座与适配器设为INF
        }

        n=tol-1; ///总节点

        printf("%d\n",M-Edmond_Karp());



    }
    return 0;
}




 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值