n个插座,m个电器,k个适配器。
建图:
原点s到电器 容量1
电器到插座 容量1
插座到终点 容量1
插座到适配器 容量inf
要哭出来了。。。。。要建双向边!!!!不过方向容量0
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<algorithm> 4 #include<map> 5 #include<iostream> 6 #include<string> 7 using namespace std; 8 const int maxn = 505; 9 const int maxm = 20005; 10 const int inf = 99999999; 11 int cnt,head1[ maxn ]; 12 int rece[ maxn ]; 13 struct node{ 14 int from,to,val,next; 15 }edge[ maxm ]; 16 map<string,int>mp; 17 int s,t; 18 void init(){ 19 cnt=0; 20 mp.clear(); 21 memset( head1,-1,sizeof( head1 )); 22 } 23 void addedge( int a,int b,int c ){ 24 edge[ cnt ].from=a; 25 edge[ cnt ].to=b; 26 edge[ cnt ].val=c; 27 edge[ cnt ].next=head1[ a ]; 28 head1[ a ]=cnt++; 29 edge[ cnt ].from=b; 30 edge[ cnt ].to=a; 31 edge[ cnt ].val=0; 32 edge[ cnt ].next=head1[ b ]; 33 head1[ b ]=cnt++; 34 } 35 int queue[ 1005 ]; 36 int lev[ maxn ]; 37 int Dinic( int start,int end ){ 38 int max_flow=0; 39 while(true){ 40 // printf("dinic100\n"); 41 int head,tail,id,i; 42 head=tail=0; 43 queue[tail++]=start;//队列从0开始,tail指向下一个入队元素的位置,head指向出队元素 44 memset(lev,-1,sizeof(lev)); 45 lev[start]=0; 46 while(head<tail){ 47 id=head1[queue[head++]]; 48 while(id!=-1){ 49 // printf("dinic200\n"); 50 if(edge[id].val>0&&lev[edge[id].to]==-1){ 51 lev[edge[id].to]=lev[edge[id].from]+1; 52 queue[tail++]=edge[id].to; 53 if(edge[id].to==end){ 54 head=tail; 55 break;//end of while(head<tail) 56 } 57 } 58 id=edge[id].next; 59 } 60 }//分层,直到找到end为止,分层结束 61 62 if(lev[end]==-1) 63 break;//end of while(true) 64 65 id=start; 66 tail=0; 67 while(true){//寻找增广路 68 // printf("dinic300\n"); 69 if(id==end){//找到了一条增广路 70 int flow=inf,flag=-1; 71 for(i=0;i<tail;i++){ 72 if(edge[queue[i]].val<flow){ 73 flag=i; 74 flow=edge[queue[i]].val; 75 } 76 //寻找最短的 77 } 78 for(i=0;i<tail;i++){ 79 // printf("%d ",edge[queue[i]].from); 80 edge[queue[i]].val-=flow; 81 edge[queue[i]^1].val+=flow; 82 } 83 // printf("\nmax_flw:%d\n",max_flow); 84 if(flag!=-1){ 85 max_flow+=flow; 86 tail=flag; 87 id=edge[queue[flag]].from; 88 } 89 else 90 return inf; 91 } 92 id=head1[id]; 93 while(id!=-1){ 94 // printf("dinic400\n"); 95 if(edge[id].val>0&&(lev[edge[id].from]+1==lev[edge[id].to])) 96 break; 97 id=edge[id].next; 98 } 99 if(id!=-1){ 100 queue[tail++]=id; 101 id=edge[id].to; 102 } 103 else{ 104 if(tail==0) 105 break; 106 lev[edge[queue[tail-1]].to]=-1; 107 id=edge[queue[--tail]].from; 108 } 109 } 110 } 111 return max_flow; 112 } 113 114 115 int main(){ 116 int n,m,k; 117 string name,pname; 118 while( scanf("%d",&n)!=EOF ){ 119 init(); 120 s=0; 121 int CNT=1; 122 for( int i=0;i<n;i++ ){ 123 cin>>name; 124 mp[ name ]=CNT; 125 CNT++; 126 } 127 scanf("%d",&m); 128 int t1,t2; 129 int tot=m; 130 while( m-- ){ 131 cin>>name>>pname; 132 if( mp[ name ]==0 ){ 133 mp[ name ]=CNT; 134 t1=CNT; 135 CNT++; 136 } 137 else 138 t1=mp[ name ]; 139 if( mp[ pname ]==0 ){ 140 mp[ pname ]=CNT; 141 t2=CNT; 142 CNT++; 143 } 144 else 145 t2=mp[ pname ]; 146 addedge( s,t1,1 ); 147 addedge( t1,t2,1 ); 148 } 149 scanf("%d",&k); 150 while( k-- ){ 151 cin>>name>>pname; 152 if( mp[ name ]==0 ){ 153 mp[ name ]=CNT; 154 t1=CNT; 155 CNT++; 156 } 157 else 158 t1=mp[ name ]; 159 if( mp[ pname ]==0 ){ 160 mp[ pname ]=CNT; 161 t2=CNT; 162 CNT++; 163 } 164 else 165 t2=mp[ pname ]; 166 addedge( t1,t2,inf ); 167 } 168 for( int i=1;i<=n;i++ ) 169 addedge( i,maxn-1,1 ); 170 171 int ans=Dinic( 0,maxn-1 ); 172 printf("%d\n",tot-ans); 173 } 174 return 0; 175 }