还是用kruskal算法,只不过把最短路换成了最大路,还只能留下最大的k条路。可以说是最大生成树?
//第一遍的代码,结果错了,发现是美丽度最大,然后就把cmp函数里的<改成了>,很奇怪,不出结果
#include<bits/stdc++.h>
using namespace std;
const int K=100005;
int parent[K];
int n,m,k;
int cnt=0,maxlen=0;// K 条地毯的最大美丽度之和
struct Edge
{
int u,v,w;//两顶点和一边 , u 和 v 为地毯连接的两个关键区域编号,w 为这条地毯的美丽度
}edge[K];
void initial()//初始化
{
for(int i=1;i<=n;i++)
{
parent[i]=-1;
}
}
int find_root(int x)
{
int x_root=x;
while(parent[x_root]!=-1)
{
x_root=parent[x_root];
}
return x_root;
}
inline bool cmp(Edge a,Edge b)
{
return a.w>b.w;
}
inline void kruskal()
{
sort(edge,edge+m,cmp);//将边按权值排序
for(register int i=1;i<=m;i++)//重新接上m条边
{
//用到了并查集
int x_root=find_root(edge[i].u);
int y_root=find_root(edge[i].v);
if(x_root==y_root)
{
continue;//两个点已经连通,不再需要这条边
}
maxlen+=edge[i].w;//未连通则将此边权值加入总长
parent[y_root]=x_root,cnt++;//连接两节点,边数+1
if(cnt==n-1)
{
break;//接上的边数为n-1时,最小生成树创立完毕,循环结束
}
}
}
int main()
{
cin>>n>>m>>k;// n 个关键区域, m 条无向地毯,只能保留 K 条地毯
for(int i=1;i<=m;i++)
{
cin>>edge[i].u>>edge[i].v>>edge[i].w;
}
initial();
kruskal();
if(cnt>k)
{
for(int i=n-1;i>k;i--)
{
maxlen-=edge[i].w;
}
}
cout<<maxlen;
return 0;
}
改了一下,没动cmp了,把循环换成了。
0分。。。无语了,我觉得没啥问题了
#include<bits/stdc++.h>
using namespace std;
const int K=100005;
int parent[K];
int n,m,k;
int cnt=0,maxlen=0;// K 条地毯的最大美丽度之和
struct Edge
{
int u,v,w;//两顶点和一边 , u 和 v 为地毯连接的两个关键区域编号,w 为这条地毯的美丽度
}edge[K];
void initial()//初始化
{
for(int i=1;i<=n;i++)
{
parent[i]=-1;
}
}
int find_root(int x)
{
int x_root=x;
while(parent[x_root]!=-1)
{
x_root=parent[x_root];
}
return x_root;
}
inline bool cmp(Edge &a,Edge &b)
{
return a.w<b.w;
}
inline void kruskal()
{
sort(edge,edge+m,cmp);
for(register int i=m;i>=1;i--)
{
int x_root=find_root(edge[i].u);
int y_root=find_root(edge[i].v);
if(x_root==y_root)
{
continue;
}
maxlen+=edge[i].w;
parent[y_root]=x_root,cnt++;
if(cnt==k)
{
break;
}
}
}
int main()
{
cin>>n>>m>>k;// n 个关键区域, m 条无向地毯,只能保留 K 条地毯
for(int i=1;i<=m;i++)
{
cin>>edge[i].u>>edge[i].v>>edge[i].w;
}
initial();
kruskal();
cout<<maxlen;
return 0;
}
AC代码
#include<bits/stdc++.h>
using namespace std;
const int K=100005;
int parent[K];
int n,m,k;
int maxlen=0;
struct Edge
{
int u,v,w;
}edge[K];
bool cmp (const Edge & a,const Edge &b)
{
return a.w>b.w;
}
int find_root(int x)
{
int x_root=x;
while(parent[x_root]!=-1)
{
x_root=parent[x_root];
}
return x_root;
}
void kruskal()
{
sort(edge+1,edge+m+1,cmp);
for(int i=1,cnt=0;i<=m&&cnt<k;i++)
{
int x_root=find_root(edge[i].u);
int y_root=find_root(edge[i].v);
if(x_root!=y_root)
{
parent[x_root]=y_root;
cnt++;
maxlen+=edge[i].w;
}
}
}
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=m;i++)
{
cin>>edge[i].u>>edge[i].v>>edge[i].w;
}
for(int i=1;i<=n;i++)
{
parent[i]=-1;
}
kruskal();
cout<<maxlen;
return 0;
}