POJ 1087 A Plug for UNIX_庒谐的空间_百度空间

       题意:有插座以及用电器和适配器,用电器有插头,适配器本身有一个插孔和插头,它的作用是可以把别的插头插入到适合该适配器插孔的适配器,然后就可以用适配器的插头接到适合的插座,相当于转换插头的作用,每个插座只能插入一个插头,3种东西都最多有100个,但是任一种适配器可以有无限个(but there is essentially an unlimited supply of the ones they do have.),求解{zh1}不能完成充电的最小的用电器数目.

        用{zd0}流问题的增广路算法来求解该问题:将每一种插头看成一个点,每一个用电器看成一个点,然后构图.用电器可以插入对应的插座,所以该用电器这个点可以和该插座对应的插头种类这个点连线,且该连线的权值为1,而由于适配器有无数个,所以将适配器的插孔和所对应的插头或适配器的插头连线,权值为INF,然后再加上虚源点和虚汇点,令虚源点和所有用电器所对应的节点连接,且连接所得到的边的权值为1,n个插座插头所对应的节点与虚汇点相连接,且置连接后得到的边的权值为1.
#include<iostream>
#include<cstdlib>
#include<queue>
#include<string>
#include<map>
#include<algorithm>
using namespace std;

const int INF=1000000000;
const int MAXN=505;

int n, m, S, T;
int a[MAXN], p[MAXN], cap[MAXN][MAXN], flow[MAXN][MAXN];

map<string,int>mp;                                        //这里用map容器来进行字符串的处理

int main()
{

     int i,j,u,v,w,k,x,y,ans,t;
     queue<int>q;
     char s1[30],s2[30];
     string ss,s;
     while(scanf("%d",&n)!=EOF)
     {
        memset(flow,0,sizeof(flow));
        memset(cap,0,sizeof(cap));
        ans=0;                                              //{zd0}流值
        S=0;                                               //源点
        for(i=1;i<=n;i++)
        {
            scanf("%s",&s1);
            ss=s1;
            mp[ss]=i;
        }
        scanf("%d",&m);
        for(t=n,i=1;i<=m;i++)
        {
           scanf("%s%s",s1,s2);
           ss=s2;
           if(mp[ss]==0)                                //此时说明字符串ss是新增进来的节点
           {
              t++;
              mp[ss]=t;
           }
           cap[i][m+mp[ss]]=1;                          //注意这里将用电器从1到m开始编号,而插座所对应的节点从(m+1)开始编号
        }
        scanf("%d",&k);
        for(i=1;i<=k;i++)
        {
            scanf("%s%s",s1,s2);
            ss=s1;
            if(mp[ss]==0)                                //同理此时字符串s1是新增进来的节点
            {
              t++;
              mp[ss]=t;
            }
            ss=s2;
            if(mp[ss]==0)                               //同上
            {
              t++;
              mp[ss]=t;
            }
            s=s1;
            cap[m+mp[s]][m+mp[ss]]=INF;                //因为适配器可以有无数多个,所以将所对应的边的权值置为无穷大(开始这里一直置为1,错了几次不知道原因,后来看讨论才知道)
        }
        for(i=1;i<=m;i++)                                  //将虚源点到各用电器所对应的节点的距离置为1
           cap[S][i]=1;
        T=m+t+1;                                              //汇点
        for(i=1;i<=n;i++)                                     //将各充电器所对应的节点和虚汇点的距离置为1
           cap[m+i][T]=1;
        while(1)
        {
                memset(a,0,sizeof(a));
                a[S]=INF;
                q.push(S);
                while(!q.empty())                        //BFS找增光路径
                {
                                 u=q.front();
                                 q.pop();
                                 for(v=1;v<=T;v++)
                                   if(!a[v]&&cap[u][v]>flow[u][v])
                                    {
                                                  p[v]=u;
                                                  q.push(v);
                                                  a[v]=min(a[u],cap[u][v]-flow[u][v]);      //求最短路径上的最小残留量
                                    }
                }
                if(a[T]==0)                                                                          //找不到,则当前流已经是{zd0}流
                   break;
                for(u=T;u!=S;u=p[u])                                                         //从汇点往回走
                {
                    flow[p[u]][u]+=a[t];                                                          //更新正向流量
                    flow[u][p[u]]-=a[t];                                                            //更新方向流量
                }
                ans+=a[T];
        }
        printf("%d\n",m-ans);                                                                    //注意{zh1}输出的是不能完成充电的用电器的最小数目
     }
     system("pause");
     return 0;
}



郑重声明:资讯 【POJ 1087 A Plug for UNIX_庒谐的空间_百度空间】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——