Uva_753
We can regard the adapter as a directed edge, while the plug and socket are regarded as two points. At the same time, a source point is introduced to connect with devices, and a sink point is connected to javastacles, at the same time, because the adapter is unlimited, the edge weight of the adapter is INF, And the Edge Weight of the directed edge connected to the Source Vertex and devices, and the Edge Weight of the directed tacles connected to the sink vertex is 1.
After creating the graph, find the maximum stream from the source point to the sink point, and then subtract the maximum stream from m, which is the final result.
However, the adapter is actually used to connect the device to the corresponding secondary tacle. Therefore, we can use Floyd to find the secondary tacle that each device can connect directly or indirectly based on the type of the current adapter, in this way, we only need to use Hungary.AlgorithmObtain the maximum matching value for a bipartite graph.
(The followingProgramIs written using network stream algorithms)
# Include <stdio. h>
# Include <String . H>
# Define Maxd 510
# Define Maxn 110
# Define Maxm 1010
# Define INF 1000000000
Char STR [ 30 ], St [maxd] [ 30 ], Name [maxn] [ 30 ], Plug [maxn] [ 30 ];
Int N, m, K, size, E, first [maxd], V [maxm], next [maxm];
Int Flow [maxm], d [maxd], work [maxd], Q [maxd];
Void Add ( Int X, Int Y, Int F)
{
V [e] = y;
Flow [e] = F;
Next [e] = first [x];
First [x] = E;
E ++;
}
Void Init ()
{
Int I, j, X, Y;
E = 0 ;
Size = 2 ;
Memset (first ,- 1 , Sizeof (First ));
Scanf ( " % D " , & N );
For (I = 0 ; I <n; I ++)
{
Scanf (" % S " , St [size]);
Add (size, 1 , 1 );
Add ( 1 , Size, 0 );
Size ++;
}
Scanf ( " % D " , & M );
For (I =1 ; I <= m; I ++)
Scanf ( " % S % s " , Name [I], plug [I]);
Scanf ( " % D " , & K );
For (I = 0 ; I <K; I ++)
{
Scanf ( " % S " , STR );
For (X = 2 ; X <size; X ++)
If (Strcmp (STR, St [x]) = 0 )
Break ;
If (X = size)
{
Strcpy (ST [size], STR );
Size ++;
}
Scanf ( " % S " , STR );
For (Y = 2 ; Y <size; y ++)
If (Strcmp (STR, St [y]) = 0 )
Break ;
If (Y = size)
{
Strcpy (ST [size], STR );
Size ++;
}
Add (X, Y, INF );
Add (Y, X, 0 );
}
For (I = 1 ; I <= m; I ++)
{
For (X = 2 ; X <size; X ++)
If (Strcmp (plug [I], St [x]) = 0 )
Break ;
If (X! = Size)
{
Add ( 0 , Size + I, 1 );
Add (size + I, 0 , 0 );
Add (size + I, X, 1 );
Add (x, size + I, 0 );
}
}
}
Int BFS ()
{
Int I, j, rear;
Memset (D ,- 1 , Sizeof (D ));
D [ 0 ] = 0 ;
Rear = 0 ;
Q [rear ++] = 0 ;
For (I = 0 ; I <rear; I ++)
For (J = first [Q [I]; J! =- 1 ; J = next [J])
If (Flow [J] & D [V [J] =- 1 )
{
D [V [J] = d [Q [I] + 1 ;
If (V [J] = 1 )
Return 1 ;
Q [rear ++] = V [J];
}
Return 0 ;
}
Int DFS ( Int Cur, Int A)
{
If (Cur = 1 )
Return A;
For ( Int & I = work [cur]; I! =- 1 ; I = next [I])
If (Flow [I] & D [V [I] = d [cur] + 1 )
If ( Int T = DFS (V [I], flow [I] <? Flow [I]: ))
{
Flow [I]-= T;
Flow [I ^ 1 ] + = T;
Return T;
}
Return 0 ;
}
Int Dinic ()
{
Int T, Res = 0 ;
While (BFS ())
{
Memcpy (work, first, Sizeof (First ));
While (T = DFS ( 0 , INF ))
Res + = T;
}
Return Res;
}
Int Main ()
{
Int I, T;
Scanf ( " % D " , & T );
For (I = 0 ; I <t; I ++)
{
Init ();
If (I)
Printf ( " \ N " );
Int Res = dinic ();
Printf ( " % D \ n " , M-res );
}
Return 0 ;
}