题目分析:最小树形图模板题。。。。。
码完以后调都没调试,交上去一遍AC。。。。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define REP( i , a , b ) for ( int i = a ; i < b ; ++ i )
#define REV( i , a , b ) for ( int i = a - 1 ; i >= b ; -- i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define FOV( i , a , b ) for ( int i = a ; i >= b ; -- i )
#define CLR( a , x ) memset ( a , x , sizeof a )
const int MAXN = 1005 ;
const int MAXE = 40005 ;
const int INF = 0x3f3f3f3f ;
struct Edge {
int u , v , c ;
} ;
struct Directed_MST {
Edge E[MAXE] ;
int in[MAXN] ;
int idx[MAXN] ;
int vis[MAXN] ;
int p[MAXN] ;
int root ;
int res ;
int NV , NE ;
int zhuliu () {
res = 0 ;
root = 0 ;
while ( 1 ) {
REP ( i , 0 , NV )
in[i] = INF ;
REP ( i , 0 , NE ) {
int u = E[i].u ;
int v = E[i].v ;
if ( u != v && in[v] > E[i].c ) {
in[v] = E[i].c ;
p[v] = u ;
}
}
REP ( i , 0 , NV )
if ( in[i] == INF && i != root )
return 0 ;
int cnt = 0 ;
CLR ( vis , -1 ) ;
CLR ( idx , -1 ) ;
in[root] = 0 ;
REP ( i , 0 , NV ) {
res += in[i] ;
int v = i ;
while ( vis[v] != i && idx[v] == -1 && v != root ) {
vis[v] = i ;
v = p[v] ;
}
if ( idx[v] == -1 && v != root ) {
for ( int u = p[v] ; u != v ; u = p[u] )
idx[u] = cnt ;
idx[v] = cnt ++ ;
}
}
if ( !cnt )
break ;
REP ( i , 0 , NV )
if ( idx[i] == -1 )
idx[i] = cnt ++ ;
REP ( i , 0 , NE ) {
int u = E[i].u ;
int v = E[i].v ;
E[i].u = idx[u] ;
E[i].v = idx[v] ;
if ( idx[u] != idx[v] )
E[i].c -= in[v] ;
}
NV = cnt ;
root = idx[root] ;
}
return 1 ;
}
void solve () {
scanf ( "%d%d" , &NV , &NE ) ;
REP ( i , 0 , NE )
scanf ( "%d%d%d" , &E[i].u , &E[i].v , &E[i].c ) ;
if ( zhuliu () )
printf ( "%d\n" , res ) ;
else
printf ( "Possums!\n" ) ;
}
} z ;
int main () {
int T , cas = 0 ;
scanf ( "%d" , &T ) ;
while ( T -- ) {
printf ( "Case #%d: " , ++ cas ) ;
z.solve () ;
}
return 0 ;
}