hdu4313 贪心+并查集
题意简单思路也还可以。开始从小到大排序非常烦。后来从大到小就很简单了;
从大到小解决了删除的边最小。
#include<stdio.h> #include<string.h> #include<algorithm> #define maxn 100010 using namespace std; #define LL long long struct node { int x,y; LL v; }edge[maxn]; int pa[maxn],n,m,vis[maxn]; bool cmp(node a,node b) { return a.v>b.v; } void init() { int i; for(i=0;i<=n;i++) pa[i]=i; } int find (int x) { if(x!=pa[x]) pa[x]=find(pa[x]); return pa[x]; } void kruskal() { int i,j; LL ans=0; for(i=0;i<n-1;i++) { int fx=find(edge[i].x); int fy=find(edge[i].y); if(vis[fx]&&vis[fy]) { ans+=edge[i].v; } else if(vis[fx]) pa[fy]=fx; else if(vis[fy]) pa[fx]=fy; else pa[fx]=fy; } printf("%I64d\n",ans); } int main() { int i,j,t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); init(); memset(vis,0,sizeof(vis)); for(i=0;i<n-1;i++) { scanf("%d%d%lld",&edge[i].x,&edge[i].y,&edge[i].v); } for(i=0;i<m;i++) { int c; scanf("%d",&c); vis[c]=1; } sort(edge,edge+n-1,cmp); kruskal(); } }