分析题目的时候注意到从最初的插座经过适配器再到最终的电器设备是一条路径,这条路径由插销连接到一起,题目中最后似乎要求能够得到多少条类似的路径。由此可以想到通过网络流解决。
网络流解决问题的关键是判断出图节点表达什么意思,路径表达什么意思。
每个路径都有一个源点和终点,可以把路径看成是电线,而节点看成是电线尽头是什么插座。
网络流算法需要求增广路径,在填充流,注意在一个方向填充流的时候要在相反方向上减少该流。
#include<iostream>
#include<vector>
#include<map>
#include<string>
#define INF 99999
#define MAXNUM 420
using namespace std;
map<string,int> names;
int cap[MAXNUM][MAXNUM];
int flow[MAXNUM][MAXNUM];
int n;
int m;
int k;
int maxid;
int id = 2;
bool mark[1001];
vector<int> pathlist;
void getPair(pair<string,int>& tmp);
void input();
void slove();
int findpath(int from);
void init();
int remain(int i,int j){
return cap[i][j] - flow[i][j];
}
int main(){
init();
input();
slove();
}
void init(){
int i,j;
for(i=0;i<MAXNUM;i++)
for(j=0;j<MAXNUM;j++){
cap[i][j] = 0;
flow[i][j] = 0;
}
}
int findpath(int from){
int i;
if(mark[from] == false){
mark[from] = true;
for(i=1;i<=maxid;i++){
if(flow[from][i] < cap[from][i]){
if(i == 2){
pathlist.push_back(i);
pathlist.push_back(from);
return 1;
}else{
if(findpath(i)){
pathlist.push_back(from);
return 1;
}
}
}
}
}
return 0;
}
void slove(){
int i,len,comp;
memset(mark,false,1001);
while(findpath(1)){
len = pathlist.end() - pathlist.begin();
comp = remain(pathlist[len-1],pathlist[len-2]);
for(i=len-1;i>1;i--){
if(comp > remain(pathlist[i-1],pathlist[i-2]))
comp = remain(pathlist[i-1],pathlist[i-2]);
}
for(i=len;i>1;i--){
flow[pathlist[i-1]][pathlist[i-2]] += comp;
flow[pathlist[i-2]][pathlist[i-1]] -= comp;
}
pathlist.clear();
memset(mark,false,1001);
}
for(i=1,comp=0;i<=maxid;i++)
comp += flow[1][i];
cout<<m-comp<<endl;
}
void getPair(pair<string,int>& tmp){
map<string,int>::iterator pNames;
if((pNames=names.find(tmp.first)) == names.end()){
tmp.second = ++id;
names.insert(tmp);
}else
tmp = *pNames;
}
void input(){
int i,j,l;
pair<string,int> tmp;
cin>>n;
for(i=0;i<n;i++){
cin >> tmp.first;
getPair(tmp);
cap[1][tmp.second]++;
}
cin>>m;
for(i=0;i<m;i++){
cin >> tmp.first >> tmp.first;
getPair(tmp);
cap[tmp.second][2]++;
}
cin>>k;
for(i=0;i<k;i++){
cin>>tmp.first;
getPair(tmp);
j = tmp.second;
cin>>tmp.first;
getPair(tmp);
l = tmp.second;
cap[l][j] = INF;
}
maxid = id;
}