看这里即可
AC
#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#define mst(x, a) memset(x,a, sizeof(x))
#define sz(a) (int)a.size()
#define For(i,x,y) for(int i=(x); i<=(y); i++)
#define fori(i,x,y) for(int i=(x); i<(y); i++)
#define pb push_back
#define fzhead EDGE(int u, int v, int c, int f, double w)
#define fzbody from(u), to(v), cap(c), flow(f), cost(w)
using namespace std;
const double eps = 1e-8 ;
const double INF = 1e38 ;
const int inf = 0x3f3f3f3f ;
const int maxn = 110 ;
struct EDGE{
int from, to, cap, flow;
double cost;
EDGE ( ) { }
fzhead : fzbody { }
} ;
struct MCMF{
int n, m, s, t;
vector< EDGE> edges;
vector< int > G[ maxn] ;
int inq[ maxn] ;
double d[ maxn] ;
int p[ maxn] ;
int a[ maxn] ;
void init ( int n) {
this - > n = n;
fori ( i, 0 , n) G[ i] . clear ( ) ;
edges. clear ( ) ;
}
void AddEdge ( int from, int to, int cap, double cost) {
edges. pb ( { from, to, cap, 0 , cost} ) ;
edges. pb ( { to, from, 0 , 0 , - cost} ) ;
m = edges. size ( ) ;
G[ from] . pb ( m- 2 ) ;
G[ to] . pb ( m- 1 ) ;
}
bool BellmanFord ( int s, int t, int & flow, double & cost) {
fori ( i, 0 , n) d[ i] = INF;
mst ( inq, 0 ) ;
d[ s] = 0 ; inq[ s] = 1 ; p[ s] = 0 ; a[ s] = inf;
queue< int > q; q. push ( s) ;
while ( ! q. empty ( ) ) {
int x = q. front ( ) ; q. pop ( ) ;
inq[ x] = 0 ;
fori ( i, 0 , sz ( G[ x] ) ) {
EDGE& e = edges[ G[ x] [ i] ] ;
if ( e. cap > e. flow && d[ e. to] > d[ x] + e. cost) {
d[ e. to] = d[ x] + e. cost;
p[ e. to] = G[ x] [ i] ;
a[ e. to] = min ( a[ x] , e. cap - e. flow) ;
if ( ! inq[ e. to] ) { q. push ( e. to) ; inq[ e. to] = 1 ; }
}
}
}
if ( d[ t] == INF) return false ;
flow + = a[ t] ;
cost + = d[ t] * a[ t] ;
for ( int u= t; u != s; u = edges[ p[ u] ] . from) {
edges[ p[ u] ] . flow + = a[ t] ;
edges[ p[ u] ^ 1 ] . flow - = a[ t] ;
}
return true ;
}
int MincostMaxflow ( int s, int t, double & cost) {
int flow = 0 ;
while ( BellmanFord ( s, t, flow, cost) ) ;
return flow;
}
} mcmf;
int n;
int earn, lost;
int st, ed;
int x[ maxn] , y[ maxn] , degree[ maxn] ;
double ans;
vector< int > e[ maxn] ;
double getdis ( int i, int j) { return sqrt ( ( x[ i] - x[ j] ) * ( x[ i] - x[ j] ) + ( y[ i] - y[ j] ) * ( y[ i] - y[ j] ) ) ; }
void init ( ) {
scanf ( "%d%d" , & earn, & lost) ;
int u, v;
ans = 0 ;
st = 0 ; ed = n+ 1 ;
For ( i, 1 , n) e[ i] . clear ( ) , degree[ i] = 0 ;
For ( u, 1 , n) {
scanf ( "%d%d" , & x[ u] , & y[ u] ) ;
while ( scanf ( "%d" , & v) && v) e[ u] . pb ( v) ;
}
mcmf. init ( maxn) ;
For ( u, 1 , n) {
fori ( i, 0 , sz ( e[ u] ) ) {
v = e[ u] [ i] ;
double cost = lost- getdis ( u, v) * earn;
if ( cost < 0 ) {
ans + = cost;
degree[ v] -- ; degree[ u] ++ ;
mcmf. AddEdge ( v, u, 1 , - cost) ;
} else mcmf. AddEdge ( u, v, 1 , cost) ;
}
}
For ( u, 1 , n) {
if ( degree[ u] > 0 ) mcmf. AddEdge ( u, ed, degree[ u] , 0 ) ;
if ( degree[ u] < 0 ) mcmf. AddEdge ( st, u, - degree[ u] , 0 ) ;
}
}
int main ( )
{
int kase = 0 ;
while ( scanf ( "%d" , & n) && n) {
init ( ) ;
mcmf. MincostMaxflow ( st, ed, ans) ;
printf ( "Case %d: %.2f\n" , ++ kase, - ans+ eps) ;
}
return 0 ;
}