题意
有N个电源适配器,M个电器,K种配对方案,一种电源适配器可以配对另一种电源适配器。求最多能适配多少个电器。
题解
网络流最重要的就是建图啦。这道题的话,建图的时候搭配map那是相当的方便。适配器和超级源点相连,电器和终点相连。超级源点到适配器的边容量为1,电器到超级终点的边容量为1。建好图后,扔到Dinic算法里就行了。
注意事项
一定要注意网络流的方向!!!!
代码
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<iostream>
#include<queue>
#include<map>
#define MAXN 1010
#define INF 1e9
using namespace std;
struct Edge{
int from,to,cap,flow;
};
struct Dinic{
int n,m,s,t;
vector<Edge> edges;
vector<int> g[MAXN];
bool vis[MAXN];
int d[MAXN];
int cur[MAXN];
void init(int n){
this->n=n;
edges.clear();
for(int i=0;i<=n;i++)
g[i].clear();
}
void addEdge(int from,int to,int cap){
edges.push_back((Edge){from,to,cap,0});
edges.push_back((Edge){to,from,0,0});
m=edges.size();
g[from].push_back(m-2);
g[to].push_back(m-1);
}
bool bfs(){
memset(vis,0,sizeof(vis));
memset(d,-1,sizeof(d));
queue<int> q;
q.push(s);
d[s]=0;
vis[s]=true;
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=0;i<g[x].size();i++){
Edge e=edges[g[x][i]];
if(!vis[e.to]&&e.cap>e.flow){
vis[e.to]=true;
d[e.to]=d[x]+1;
q.push(e.to);
}
}
}
return vis[t];
}
int dfs(int x,int a){
if(x==t||a==0)
return a;
int flow=0,f;
for(int& i=cur[x];i<g[x].size();i++){
Edge& e=edges[g[x][i]];
if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){
e.flow+=f;
edges[g[x][i]^1].flow-=f;
flow+=f;
a-=f;
if(a==0)
break;
}
}
return flow;
}
int maxFlow(int s,int t){
this->s=s,this->t=t;
int flow=0;
while(bfs()){
memset(cur,0,sizeof(cur));
flow+=dfs(s,INF);
}
return flow;
}
};
map<string,int> mp;
int main(){
Dinic d;
string str,str1,str2;
int st=0;
int tar=1;
int tot=2;
d.init(1005);
int p;
scanf("%d",&p);
for(int i=0;i<p;i++){
cin>>str;
if(mp[str]==0)
mp[str]=tot++;
d.addEdge(st,mp[str],1);
}
int m;
scanf("%d",&m);
for(int i=0;i<m;i++){
cin>>str1>>str2;
if(mp[str1]==0)
mp[str1]=tot++;
if(mp[str2]==0)
mp[str2]=tot++;
d.addEdge(mp[str1],tar,1);
d.addEdge(mp[str2],mp[str1],1);
}
int k;
scanf("%d",&k);
for(int i=0;i<k;i++){
cin>>str1>>str2;
if(mp[str1]==0)
mp[str1]=tot++;
if(mp[str2]==0)
mp[str2]=tot++;
d.addEdge(mp[str2],mp[str1],INF);
}
printf("%d\n",m-d.maxFlow(st,tar));
}