题目链接:https://vjudge.net/problem/UVA-753
题意:有n个插座 m个设备 k种转换器,转换器每种的个数是无限的,并且可以嵌套使用,求最少剩余的设备数。
思路:整体思路就是建图,然后用floyd求出哪些设备可以通过一些转换器的使用进而用到插座,然后再用匈牙利算法求一个最大匹配。
用一个map分配每种插头或插座的id 注意所有插头或插座的类型加起来可能会达到400种,数组要开的大一点。
特别注意匈牙利算法调用时参数不能等于0
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <cstring>
#include <iostream>
#include <cmath>
#include <set>
#include <fstream>
#include <list>
#include <stack>
#include <map>
using namespace std;
int g[805][805],vis[105],match[105];
const int inf=0x3f3f3f3f;
map <string,int> mp;
vector <string> v1,v2;
vector <int> tu[1050];
void floyd(int n)
{
for(int k=1; k<n; k++)
{
for(int i=1; i<n; i++)
{
for(int j=1; j<n; j++)
{
g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
}
}
}
}
bool dfs(int x)
{
int len=tu[x].size();
for(int i=0; i<len; i++)
{
int t=tu[x][i];
if(!vis[t])
{
vis[t]=1;
if(!match[t]||dfs(match[t]))
{
match[t]=x;
return true;
}
}
}
return false;
}
int main()
{
ios::sync_with_stdio(false);
int T,kase=0;
cin>>T;
while(T--)
{
if(kase++)
{
cout<<endl;
}
mp.clear();
memset(g,inf,sizeof(g));
v1.clear();
v2.clear();
memset(match,0,sizeof(match));
for(int i=0; i<102; i++)
tu[i].clear();
int n;
cin>>n;
int id=1;
for(int i=0; i<n; i++)
{
string s;
cin>>s;
v1.push_back(s);
if(mp[s]==0)
mp[s]=id++;
}
int m;
cin>>m;
for(int i=0; i<m; i++)
{
string s1,s2;
cin>>s1>>s2;
v2.push_back(s2);
if(mp[s2]==0)
mp[s2]=id++;
}
int k;
cin>>k;
for(int i=0; i<k; i++)
{
string s1,s2;
cin>>s1>>s2;
if(mp[s1]==0)
{
mp[s1]=id++;
}
if(mp[s2]==0)
{
mp[s2]=id++;
}
int id1=mp[s1],id2=mp[s2];
g[id1][id2]=1;
}
for(int i=1; i<800; i++)
{
g[i][i]=0;
}
floyd(id);
for(int i=0; i<m; i++)
{
int id1=mp[v2[i]];
for(int j=0; j<n; j++)
{
int id2=mp[v1[j]];
if(g[id1][id2]!=inf)
{
tu[i+1].push_back(j);
}
}
}
int ans=m;
for(int i=1; i<=m; i++)
{
memset(vis,0,sizeof(vis));
if(dfs(i))
{
ans--;
}
}
cout<<ans<<endl;
}
return 0;
}