poj_1087 A Plug for UNIX(dinic模板完美使用)

题意:n个接口不同的插板,m个有用电器有各自的接口,k种可进行接口转换的适配器(数量不限),问最少多少个用电器不能用电(同时)。

分析:直接转换为典型的最大流问题,源点汇点自定,不同类型接口的插板与汇点相连权值为1;用电器与源点相连,权值为一;适配器的接口之间相连,权值为无穷大。建完图后,dinic模板一贴,完美解决。
注意:接口类型为字符串,用map映射转换。


cpp代码:


#include<iostream>
#include 
<cstdio>
#include 
<map>
#include 
<string>
#include 
<memory.h>
using namespace std;
map 
<string,int>
 mp;
const int inf = 0x7ffffff
;

#define Max 605

int flow[Max][Max],d[Max],cnt; //flow is the network
int sta,end,N; //sta is the sourse ,end is the end,N is the number of vector

bool bfs(int s)
{
       
int front=0,rear=0

       
int
 q[Max];
       memset(d,
-1,sizeof(d));  //d[] is the deep

       q[rear++]=s;  d[s]=0;
       
while(front<
rear)
       {
               
int k=q[front++
];
               
for(int i=0;i<=N;i++
)
                  
if(flow[k][i]>0&&d[i]==-1
){
                     d[i]
=d[k]+1
;
                     q[rear
++]=
i;
                  }
       }
       
if(d[end]>=0)   return true
;
       
return false
;
}

int dinic(int k,int sum)  //k is the sourse

{
      
if (k==
end)   
          
return
 sum;
      
int os =
 sum;
      
for(int i=0;i<=N&&sum;i++
)
        
if(d[i]==d[k]+1&&flow[k][i]>0
)
        {
                
int a=dinic(i,min(sum,flow[k][i])); //Deep to the end.

                flow[k][i] -= a;
                flow[i][k] 
+=
 a;
                sum 
-=
 a;
        }
      
return os-
sum;
}

int
 main()
{
    
int
 i,j,n,m,k;
    
char s[30],se[30
];
    sta 
= 0; end = N = Max - 1
;
    
while (scanf("%d",&n) !=
 EOF)
    {
         memset(flow,
0,sizeof
(flow));
         mp.clear();
         cnt 
= 0
;
         
//读入插座类型 

         for (i = 1; i <= n; i++)
         {
             scanf(
"%s"
,s);
             
if (mp.count(s) == 0
)
                 mp[s] 
= ++
cnt;
             flow[mp[s]][end] 
++
;
         } 
         
//读入用电器类型 

         scanf("%d",&m);
         
for (i = 1; i <= m; i++
)
         {
             scanf(
"%s"
,s);
             scanf(
"%s"
,s);
             
if (mp.count(s) == 0
)
                mp[s] 
= ++
cnt;
             flow[sta][mp[s]] 
++
;
         }
         
//读入适配器类型 

         scanf("%d",&k);
         
for (i = 1; i <= k; i++
)
         {
             scanf(
"%s %s"
,s,se);
             
if (mp.count(s) == 0
)
                mp[s] 
= ++
cnt;
             
if (mp.count(se) == 0
)
                mp[se] 
= ++
cnt;
             flow[mp[s]][mp[se]] 
=
 inf;
         }
         
         
int ret = 0
;
         
while
(bfs(sta))
             ret 
+=
 dinic(sta,inf);
         printf(
"%d\n",m -
 ret); 
    } 
    
    
return 0
;
}

你可能感兴趣的:(poj_1087 A Plug for UNIX(dinic模板完美使用))