题意:你作为某高管去住宿了,然后宾馆里有几种插座,分别有其对应型号,你携带了几种用电器(手机,电脑一类的),也有其对应型号;可是不一定用电器就能和插座匹配上,于是宾馆的商店里提供了一些转换器,这些转换器可以将某一型号电源转换成另一型号的。问,你的用电器最少会有多少种无法充电 摘自http://www.cnblogs.com/zznulw/p/5929247.html
思路:很显然创建一个源点和一个汇点,源点指向所有的插头,所有的插座指向汇点;
显然插头与插座之间有两种方式相连
第一种:如果插头插座型号相同,可以直接将插头指向插座
第二种:如果插头与转换器的插座型号相同 ,转换器的插头与插座型号相同,那么可以插头指向转换器,转换器指向插座
还有一种情况就是转换器之间可以再转换,如果转换器1插头与转换器2的插座型号相同 ,那么两个之间可以连接。
构图之后直接网络流跑一遍,就得出结果了。
有的说转换器可以无限使用,只需将与转换器有关的边,权值改为inf就可以了
AC代码:
//#include<bits/stdc++.h>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
#define LL long long
#define Max 100005
const LL mod=1e9+7;
const LL LL_MAX=9223372036854775807;
using namespace std;
struct node{
int v,w,next;
}edge[Max];
int head[Max],cur[Max],dis[Max],index;
int n,m,k;
int st,en;
queue<int>p;
void init()
{
index=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int w){
edge[index].v=v,edge[index].w=w;
edge[index].next=head[u],head[u]=index++;
edge[index].v=u,edge[index].w=0;
edge[index].next=head[v],head[v]=index++;
}
struct d
{
char a[30];
int index;//保存编号
}ct[Max],cz[Max];
struct dd
{
char to[30];//转换器插座
char from[30];//转换器插头
int index;//保存编号
}zhq[Max];
void add_edge()
{
for(int i=1;i<=m;i++)//将插头与插座型号相同的连接
for(int j=1;j<=n;j++){
if(strcmp(ct[i].a,cz[j].a)==0){
add(ct[i].index,cz[j].index,1);
}
}
for(int i=1;i<=n;i++)//将转换器插头与插座型号相同的相连
for(int j=1;j<=k;j++)
if(strcmp(cz[i].a,zhq[j].from)==0){
add(zhq[j].index,cz[i].index,1);
}
for(int i=1;i<=m;i++)//将插头与转换器插座型号相同的连接
for(int j=1;j<=k;j++)
if(strcmp(ct[i].a,zhq[j].to)==0){
add(ct[i].index,zhq[j].index,1);
}
for(int i=1;i<=k;i++)//将转换器插头与转换器插座型号相同的连接
for(int j=1;j<=k;j++)
if(strcmp(zhq[i].from,zhq[j].to)==0){
add(zhq[i].index,zhq[j].index,1);
}
for(int i=1;i<=n;i++){//将插座连向汇点
add(cz[i].index,n+m+k+2,1);
}
}
bool bfs()
{
memset(dis,0,sizeof(dis));
while(p.size())p.pop();
dis[st]=1;
p.push(st);
while(p.size()){
int top=p.front();
p.pop();
for(int t=head[top];t!=-1;t=edge[t].next){
if(dis[edge[t].v]==0 && edge[t].w>0){
dis[edge[t].v]=dis[top]+1;
p.push(edge[t].v);
}
}
}
return dis[en]!=0;
}
int dfs(int u,int flow){
if(u==en)
return flow;
for(int& t=cur[u];t!=-1;t=edge[t].next){
if(dis[edge[t].v]==dis[u]+1 && edge[t].w>0){
int mn=dfs(edge[t].v,min(flow,edge[t].w));
if(mn>0){
edge[t].w-=mn;
edge[t^1].w+=mn;
return mn;
}
}
}
return 0;
}
int Dinic(){
int ans=0,res;
while(bfs()){
for(int i=st;i<=en;i++)
cur[i]=head[i];
while(res=dfs(st,INT_MAX))
ans+=res;
}
return ans;
}
int main()
{
char t[105];
init();
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",cz[i].a),cz[i].index=i+1;
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%s %s",t,ct[i].a),ct[i].index=i+n+1;
add(1,i+1+n,1);//将源点与插头相连接
}
scanf("%d",&k);
for(int i=1;i<=k;i++){
scanf("%s %s",zhq[i].to,zhq[i].from);
zhq[i].index=i+n+m+1;
}
add_edge();
st=1,en=n+m+k+2;
printf("%d\n",m-Dinic());
return 0;
}