题目描述
对于完全图 ,若有且仅有一棵最小生成树为 ,则称完全图 是树 扩展出的。
给你一棵树 ,找出 能扩展出的边权和最小的完全图 。
输入格式
第一行 表示树 的点数;
接下来 行三个整数 ;描述一条边()权值为 ;
保证输入数据构成一棵树。
输出格式
输出仅一个数,表示最小的完全图 的边权和。
样例
样例输入
4
1 2 1
1 3 1
1 4 2
样例输出
12
题目给出的边是无序 双向边
若给出的是按树从上到下的边 且边值从小到大则prim可行
若给出的树从上到下的边值递增则prim可行 即保证每步prim选的d递增
WA 10分
题目给出的边是双向边 无法判断哪个是父节点
输入文件(tree1.in)
10
5 10 1
5 4 4
4 9 6
2 9 6
8 4 6
1 5 2
3 10 9
5 7 7
6 9 3
答案文件(tree1.out)
319
5 4 4
8 4 6
就算保证x<y
1 5 2
5 4 4
还是会出现一个点的父节点存在两个
故需dfs建树
#include <bits/stdc++.h> using namespace std; const int N = 10000 + 5; struct T { int p, d; }; bool cmp(T x, T y) { return x.d < y.d; } int vis[N]; T t[N]; int main() { int n, ans = 0; cin >> n; for (int i = 1; i < n; i++) { int x, y, z; cin >> x >> y >> z;//if (x>y){int t=x;x=y;y=t;} 还是不行 ans += z; t[y].p = x; t[y].d = z; } sort(t + 1, t + n + 1, cmp); for (int i = 1; i <= n; i++) { vis[i] = 1; for (int j = 1; j <= n; j++) { if ((!vis[j]) && (t[j].p != i)) ans += t[j].d + 1; } } cout << ans; return 0; }
WA 10分
#include <bits/stdc++.h> using namespace std; const int N = 10000 + 5; struct T { int id, p, d; // id }; bool cmp(T x, T y) { return x.d < y.d; } int vis[N], e[N][N], n; T t[N]; void dfs(int x) { // pre prim vis[x] = 1; for (int i = 1; i <= n; i++) { if ((!vis[i]) && (e[x][i])) { t[i].p = x; t[i].d = e[x][i]; t[i].id = i; dfs(i); } } } int main() { int ans = 0; cin >> n; for (int i = 1; i < n; i++) { int x, y, z; cin >> x >> y >> z; ans += z; e[x][y] = e[y][x] = z; } dfs(1); t[1].id = 1; sort(t + 1, t + n + 1, cmp); memset(vis, 0, sizeof(vis)); for (int i = 1; i <= n; i++) { vis[t[i].id] = 1; // vis[i] for (int j = 1; j <= n; j++) { if ((!vis[t[j].id]) && (t[j].p != t[i].id)) ans += t[j].d + 1; // vis[j] t[j].p!=i } } cout << ans; return 0; }
WA 10分
#include<bits/stdc++.h> using namespace std; const int N=10000+5; int vis[N],e[N][N],d[N],p[N],dd[N],n,ans=0; void prim(){//pre prim d[1]=0; int k,min; for(int i=1;i<=n;i++){ min=0x3f3f3f3f; for(int j=1;j<=n;j++) if((!vis[j])&&(min>d[j])){ min=d[j];k=j; } vis[k]=1;//漏了 //cout<<k<<endl; for(int j=1;j<=n;j++){ if((!vis[j])&&(d[j]>e[k][j])) d[j]=e[k][j]; else if((!vis[j])) { ans+=dd[j]+1; cout<<dd[j]+1<<endl; } } } } void dfs(int x){ vis[x]=1; for(int i=1;i<=n;i++){ if((!vis[i])&&(e[x][i]!=0x3f3f3f3f)){//e[x][i] dd[i]=e[x][i]; dfs(i); } } } int main(){ cin>>n; memset(e,0x3f,sizeof(e)); for(int i=1;i<n;i++){ int x,y,z; cin>>x>>y>>z; ans+=z; e[x][y]=e[y][x]=z; } memset(d,0x3f,sizeof(d)); dfs(1); memset(vis,0,sizeof(vis)); prim(); cout<<ans; return 0; }