题目分析:最小树形图模板题。。。。。
码完以后调都没调试,交上去一遍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 ; }