仍是最大流。
map很好用啊,自己写的change函数就TLE了,直接拿map来映射就行。。。
转换器之间边权值为MX。
VS到用电器之间权值为1,用电器到插头之间权值为1,提供的插座到VT之间权值为1.
#include<stdio.h>
#include<string.h>
#include<map>
#include<string>
#define MX 100000
using namespace std;
int h,n1,n2,n3,pre[700],queue[10000],named[30],mapp[700][700],vt,vs,deep[700];
char nam[1000][30];
struct point{
char name[100];
}it[1005];
map<string,int>mp;
int change(char s[]){
for(int i=1;i<h;i++){
if(strcmp(s,nam[i])==0){
return i;
}
}
strcpy(nam[h++],s);
return h-1;
}
int min(int a,int b){
return a<b?a:b;
}
bool bfs(){ //构建增广路
memset(deep,-1,sizeof(deep));
int qe=1,qs=0;
queue[qs]=vs;
deep[0]=0;
while(qs<qe){
int v=queue[qs++];
for(int i=1;i<=vt;i++){
if(deep[i]==-1&&mapp[v][i]){
deep[i]=deep[v]+1;
queue[qe++]=i;
}
}
}
if(deep[vt]==-1){
return false;
}
return true;
}
int dfs(int v,int num){ //Dinic,返回流量,num为从上一个流来的流量。v为上一个点。
int numcy=num;
if(v==vt){
return num;
}
else{
for(int i=0;i<=vt;i++){
if(mapp[v][i]&&deep[i]==deep[v]+1){
int p=min(num,mapp[v][i]);
int t=dfs(i,p);
mapp[v][i]-=t;
mapp[i][v]+=t;
num-=t;
// printf("! %d vt=%d t=%d\n",i,vt,t);
}
}
}
return numcy-num;
}
int main(){
while(scanf("%d",&n1)!=EOF){
memset(mapp,0,sizeof(mapp));
h=1;
mp.clear();
int sn=0;
int ans=0;
for(int i=0;i<n1;i++){
char t[5];
scanf("%s",t);
if(mp.count(t)==0){
mp[t]=++sn;
}
named[i]=mp[t];
// printf("! k=%d\n",k);
}
scanf("%d",&n2);
for(int i=1;i<=n2;i++){
char t[5];
scanf("%s%s",it[i].name,t);
if(mp.count(t)==0){
mp[t]=++sn;
}
mapp[i][mp[t]+n2]=1;
mapp[0][i]=1;
// printf("!! k=%d\n",k);
}
vs=0;
scanf("%d",&n3);
for(int i=0;i<n3;i++){
char t1[5],t2[5];
scanf("%s%s",t1,t2);
if(mp.count(t1)==0){
mp[t1]=++sn;
}
if(mp.count(t2)==0){
mp[t2]=++sn;
}
mapp[mp[t1]+n2][mp[t2]+n2]=MX;
}
vt=n2+sn+1;
for(int i=0;i<n1;i++){
mapp[named[i]+n2][vt]=1;
}
int flow=0;
/* for(int i=0;i<=vt;i++){
for(int j=0;j<=vt;j++){
printf("%d ",mapp[i][j]);
}
printf("\n");
}*/
while(bfs()){
ans+=dfs(vs,MX);
// printf("! ans=%d\n",ans);
}
printf("%d\n",n2-ans);
}
return 0;
}