intmain(){ int T; cin >> T; while (T--) { cin >> n; for (int i = 1; i <= n - 1; i++) scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z); sort(a+1, a+n); for (int i = 1; i <= n; i++) fa[i] = i, Size[i] = 1; int ans = 0; for (int i = 1; i <= n - 1; i++) { int x = get(a[i].x); int y = get(a[i].y); if (x != y) { fa[y] = x; ans += (a[i].z + 1) * (Size[x] * Size[y] - 1); //其他未连接的边权值之和 Size[x] += Size[y]; } } cout << ans << endl; } }
constint N = 25; int a[N][N], d[N], conn[N]; bool v[N]; int tree[N][N];
//用一个map做映射 voidread(){ map<string, int> h; cin >> m; h["Park"] = 1; n = 1; memset(a, 0x3f, sizeof(a)); //原图对应的邻接矩阵 for (int i = 1; i <= m; i++) { int x, y, z; char sx[12], sy[12]; scanf("%s%s%d", sx, sy, &z); if (!h[sx]) h[sx] = ++n; //节点个数+1 if (!h[sy]) h[sy] = ++n; x = h[sx], y = h[sy]; a[x][y] = min(a[x][y], z); //原图邻接矩阵存储 a[y][x] = min(a[y][x], z); } cin >> s; }
//原图的最小生成树 voidprim(){ memset(d, 0x3f, sizeof(d)); memset(v, 0, sizeof(v)); d[1] = 0; for (int i = 1; i < n; i++) { int x = 0; for (int j = 1; j <= n; j++) if (!v[j] && (x == 0 || d[j] < d[x])) x = j; v[x] = true; for (int y = 1; y <= n; y++) if (!v[y] && d[y] > a[x][y]) d[y] = a[x][y], conn[y] = x; //连接y的是x,即是(x -> y) } memset(tree, 0x3f, sizeof(tree)); //最小生成树对应的邻接矩阵 for (int i = 2; i <= n; i++) { ans += d[i]; if (conn[i] == 1) deg++; //从1节点到其他节点个数+1 tree[conn[i]][i] = tree[i][conn[i]] = d[i]; //最小生成树对应的邻接矩阵 } }
//当前连通块的所有节点都标记一下 voiddfs(int x){ v[x] = true; for (int y = 1; y <= n; y++) if (tree[x][y] != 0x3f3f3f3f && !v[y]) dfs(y); }
intfind_min(int& x, int& y){ //考虑原图中加入哪条边把v=true和v=false的两个块连起来 int min_edge = 1 << 30; for (int i = 2; i <= n; i++) if (v[i]) //是true的点 for (int j = 2; j <= n; j++) if (!v[j]) //是false的点 if (a[i][j] < min_edge) min_edge = a[i][j], x = i, y = j; //找到最小方案 return min_edge; }
voidsolve(){ int min_val = 1 << 30, mini, minx, miny; for (int i = 2; i <= n; i++) { //枚举从1出发的树边(1, i),看删去哪一条 if (tree[1][i] == 0x3f3f3f3f) continue; //如果不存在直接跳过 memset(v, 0, sizeof(v)); v[1] = true; //考虑的是1之外的两个连通块,1不能用 dfs(i); //标记当前连通块所有节点 int x, y; int add_edge = find_min(x, y); //加入(x,y),找到被标记的连通块,与false连通块连接的最小边 if (add_edge < 0x3f3f3f3f && add_edge - tree[1][i] < min_val) { min_val = add_edge - tree[1][i]; //求出最小代价 mini = i, minx = x, miny = y; //删的点,加的边 } } ans += min_val; //代价加起来 tree[1][mini] = tree[mini][1] = 0x3f3f3f3f; //删除这条边 tree[minx][miny] = tree[miny][minx] = a[minx][miny]; //添加一条边 }
intmain(){ read(); prim(); while (deg > s) { solve(); deg--; } printf("Total miles driven: %d\n", ans); return0; }
intmain(){ memset(g, 0x3f, sizeof g); int mod = (1 << 31) - 1; cin >> n >> m; for(int i = 1; i <= m; i ++) { int x, y, z; scanf("%d%d%d", &x, &y, &z); g[x][y] = g[y][x] = min(g[x][y], z); }
dijkstra(); //求最短路 memset(v, 0, sizeof v); v[1] = true; ll ans = 1; for(int i = 1; i <= n; i ++){ int x = 0, res = 0; for(int j = 2; j <= n; j ++) if(!v[j] && (x == 0 || d[x] > d[j])) x = j; for(int j = 1; j <= n; j ++) if(v[j] && d[x] == g[j][x] + d[j]) res ++; //相当于是与最短路路径相等的边的个数 v[x] = true; ans = (ans * res) % mod; //相等的边的个数相乘就是总的方案数 } printf("%lld\n", ans); return0; }