题意:图中每个节点和边都有权值,图中找出一颗树,树根为1使得 Σ(树中的节点到树根的距离)*(以该节点为子树的所有节点的权值之和) 结果最小;
分析:直接求出每个节点到树根的最短距离距离,之后乘上自身节点的权值求和即可;
ps:注意特判v = 0;这时cnt = 1 > v;
Djistra + priority_queue
//Accepted 2804K 141MS #include <cstdio> #include <cstring> #include <utility> #include <queue> #include <vector> using namespace std; #define rep0(i,l,r) for(int i = (l);i < (r);i++) #define rep1(i,l,r) for(int i = (l);i <= (r);i++) #define rep_0(i,r,l) for(int i = (r);i > (l);i--) #define rep_1(i,r,l) for(int i = (r);i >= (l);i--) #define MS0(a) memset(a,0,sizeof(a)) #define MS1(a) memset(a,-1,sizeof(a)) #define inf 1LL<<40 template<typename T> void read1(T &m) { T x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} m = x*f; } template<typename T> void read2(T &a,T &b){read1(a);read1(b);} template<typename T> void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);} template<typename T> void out(T a) { if(a>9) out(a/10); putchar(a%10+'0'); } const int N = 50050; typedef __int64 ll; typedef pair<__int64,int> lli;//距离,编号 #define A first #define B second priority_queue<lli , vector<lli> , greater<lli> > q; int v,val[N]; int head[N<<1],tot; struct edge{ int to,w,Next; }e[N<<1]; void ins(int a,int b,int w = 0) { e[++tot].Next = head[a]; e[tot].to = b; e[tot].w = w; head[a] = tot; } ll d[N];bool vis[N]; ll Djistra() { ll ans = 0,cnt = 0; d[1] = 0; q.push(lli{d[1],1}); while(!q.empty()){ lli t = q.top(); q.pop(); int u = t.B; if(vis[u]) continue; cnt++;vis[u] = true; ans += d[u]*val[u]; for(int id = head[u];id;id = e[id].Next){ int v = e[id].to,cost = e[id].w; if(d[v] > d[u] + cost){ d[v] = d[u] + cost; q.push(lli{d[v],v}); } } } if(cnt < v) return -1; return ans; } int main() { int T,e,kase = 1; read1(T); while(T--){ read2(v,e); rep1(i,1,v) read1(val[i]),d[i] = inf,vis[i] = false; MS0(head);tot = 0; rep0(i,0,e){ int a,b,w; read3(a,b,w); ins(a,b,w);ins(b,a,w); } if(v <= 1)out(0); else{ while(!q.empty()) q.pop(); ll ret = Djistra(); if(ret == -1) printf("No Answer"); else out(ret); } puts(""); } return 0; }
Djistra + heap
ps:heap中的最后的位置赋值要放在最后,不好直接在break中,因为可能是出边界了,而没有赋到需要的值;
//4116K 125MS G++ 2869B #include <cstdio> #include <cstring> #include <utility> #include <queue> #include <vector> using namespace std; #define rep0(i,l,r) for(int i = (l);i < (r);i++) #define rep1(i,l,r) for(int i = (l);i <= (r);i++) #define rep_0(i,r,l) for(int i = (r);i > (l);i--) #define rep_1(i,r,l) for(int i = (r);i >= (l);i--) #define MS0(a) memset(a,0,sizeof(a)) #define MS1(a) memset(a,-1,sizeof(a)) #define inf 1LL<<40 template<typename T> void read1(T &m) { T x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} m = x*f; } template<typename T> void read2(T &a,T &b){read1(a);read1(b);} template<typename T> void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);} template<typename T> void out(T a) { if(a>9) out(a/10); putchar(a%10+'0'); } const int N = 50050; typedef __int64 ll; typedef pair<__int64,int> lli; #define A first #define B second int v,val[N]; int head[N<<1],tot; struct edge{ int to,w,Next; }e[N<<1]; void ins(int a,int b,int w = 0) { e[++tot].Next = head[a]; e[tot].to = b; e[tot].w = w; head[a] = tot; } ll d[N];bool vis[N]; lli heap[N],q[N];int _cnt; bool comp(lli x,lli y) { return x.A < y.A;//最小堆 } inline void push(const lli x) { heap[++_cnt] = x; int son,fa; for(son = _cnt,fa = son>>1;fa >= 1;son = fa,fa = son>>1){ if(comp(x,heap[fa])) heap[son] = heap[fa]; else break; } heap[son] = x; } inline lli top() { return heap[1]; } inline void pop() { lli tmp = heap[1] = heap[_cnt--]; int son ,fa; for(fa = 1,son = fa<<1;son <= _cnt;fa = son,son = fa<<1){ if(son < _cnt && comp(heap[son|1],heap[son])) son++; if(comp(tmp,heap[son]))break; else heap[fa] = heap[son]; } heap[fa] = tmp; } ll Djistra() { ll ans = 0,cnt = 0; d[1] = 0; push(lli{d[1],1}); while(_cnt){ lli t = top(); pop(); int u = t.B; if(vis[u]) continue; cnt++;vis[u] = true; ans += d[u]*val[u]; for(int id = head[u];id;id = e[id].Next){ int v = e[id].to,cost = e[id].w; if(d[v] > d[u] + cost){ d[v] = d[u] + cost; push(lli{d[v],v}); } } } if(cnt < v) return -1; return ans; } int main() { int T,e,kase = 1; read1(T); while(T--){ read2(v,e); rep1(i,1,v) read1(val[i]),d[i] = inf,vis[i] = false; MS0(head);tot = 0; rep0(i,0,e){ int a,b,w; read3(a,b,w); ins(a,b,w);ins(b,a,w); } if(v <= 1)out(0); else{ _cnt = 0; ll ret = Djistra(); if(ret == -1) printf("No Answer"); else out(ret); } puts(""); } return 0; }