pku 3013 - nazgul's Blog
pku 3013
nazgul
posted @ 2010年10月28日 00:40
in POJ
, 1258 阅读
题目不太好理解.思路:首先对于一个点Vi,有多少个点以它为后代,经分析可以知道从root到Vi的最短路径中所有的点都会把Vi当做后代点.对于其他每个点,Vi贡献应该为sum{weight[Vi]*dist[k],k是所有以Vi为后代的点}.
题目需要注意几点:
1. root到每个点的距离可能超过int,所以对于dist要用long long.
2. 点的个数为0或1个的时候要特殊判断.
3. 边是双向的.
看其他牛的解题报告的时候,发现自己写个输入函数更快,所以也自己写了个.最后125ms.
#include <stdio.h> #include <string.h> #define MAXN 51001 #define NIL 922337203685477580 typedef long long IIL; struct _Node { int v, next, w; }edge[2*MAXN+100]; int queue[MAXN+100], visit[MAXN], g[MAXN], weight[MAXN]; IIL dist[MAXN]; int v, e, p; void SPFA( int s, int N ) { int h, t, x, i, tt, vv; IIL *temp = dist; for ( i = 0; i <= N; ++i ) *temp++ = NIL; memset( visit, 0, sizeof( visit ) ); dist[s] = 0; h = 0; t = 1; queue[0] = s; visit[s] = 1; while ( h != t ) { x = queue[h]; visit[x] = 0; for ( i = g[x]; i != -1; i = edge[i].next ) { tt = edge[i].w; vv = edge[i].v; if ( dist[vv] - tt > dist[x] ) { dist[vv] = dist[x] + tt; if ( !visit[vv] ) { queue[t] = vv; visit[vv] = 1; if ( ++t >= N ) t = 0; } } } if ( ++h >= N ) h = 0; } } void addEdge( int u, int v, int w ) { edge[p].next = g[u]; edge[p].v = v; edge[p].w = w; g[u] = p++; } int GetInt() { char ch; int t = 0; while ( ( ch = getchar() ) != EOF ) { if ( ch >= '0' && ch <= '9' ) break; } do { if ( ch < '0' || ch > '9' ) return t; t = ( t << 3 ) + ( t << 1 ) + ch - '0'; }while ( ( ch = getchar() ) != EOF ); } int main() { int cases, i, uu, vv, ww; IIL ans; //scanf( "%d", &cases ); cases = GetInt(); while ( cases-- ) { memset( g, -1, sizeof( g ) ); //scanf( "%d%d", &v, &e ); v = GetInt(); e = GetInt(); for ( i = 0; i < v; ++i ) weight[i] = GetInt(); //scanf( "%d", &weight[i] ); for ( p = i = 0; i < e; ++i ) { //scanf( "%d%d%d", &uu, &vv, &ww ); uu = GetInt(); vv = GetInt(); ww = GetInt(); addEdge( uu-1, vv-1, ww ); addEdge( vv-1, uu-1, ww ); } if ( v == 0 || v == 1 ) { printf( "0\n" ); continue; } SPFA( 0, v ); for ( ans = 0, i = 0; i < v; ++i ) { if ( dist[i] == NIL ) break; ans += dist[i]*weight[i]; } if ( i == v ) printf( "%lld\n", ans ); else printf( "No Answer\n" ); } return 0; }