DES:计算输的最小费用。如果不能构成树。输出-1。每条边的费用=所有的子节点权值*这条边的权值。计算第二组样例可以知道树的费用是所有的节点的权值*到根节点的最短路径的长度。
用dij的邻接矩阵形式直接MLE。编译都通不过。换邻接表的形式。然后。。。。模板。。。
#include<stdio.h> #include<string.h> #include<stdio.h> #include<iostream> #include<queue> using namespace std; #define maxn 50010 #define inf 10000000000 int head[maxn]; int vis[maxn]; int w[maxn]; long long dis[maxn]; int edgeNum; struct Edge { int v, c, nxt; }edge[maxn*2]; struct Node { int u, dis; bool operator < (const Node &a) const { return dis > a.dis; } }; void init() { edgeNum = 0; for (int i=0; i<maxn; ++i) { head[i] = -1; dis[i] = inf; vis[i] = 0; } } void addEdge(int a, int b, int c) { edge[edgeNum].v = b; edge[edgeNum].c = c; edge[edgeNum].nxt = head[a]; head[a] = edgeNum++; } void Dijkstra(int u) { Node temp, now; priority_queue<Node>q; temp.u = u; temp.dis = 0; dis[u] = 0; q.push(temp); while(!q.empty()) { temp = q.top(); q.pop(); if (vis[temp.u]) continue; vis[temp.u] = 1; for (int i=head[temp.u]; i!=-1; i=edge[i].nxt) { int v = edge[i].v; if (!vis[v] && dis[v] > dis[temp.u] + edge[i].c) { dis[v] = dis[temp.u] + edge[i].c; now.u = v; now.dis = dis[v]; q.push(now); } } } return; } int main() { int t, a, b, c, n, m; scanf("%d", &t); while(t--) { init(); scanf("%d%d", &n, &m); for (int i=0; i<n; ++i) { scanf("%d", &w[i]); } for (int i=0; i<m; ++i) { scanf("%d%d%d", &a, &b, &c); a--, b--; addEdge(a, b, c); addEdge(b, a, c); } Dijkstra(0); int i; long long ans = 0; for (i=0; i<n; ++i) { if (dis[i] == inf) { break; } ans += dis[i] * w[i]; } if (i == n)printf("%lld\n", ans); else printf("No Answer\n"); } return 0; }
时间: 2024-12-20 14:11:49