AcWing 1143. 联络员
Tyvj已经一岁了,网站也由最初的几个用户增加到了上万个用户,随着Tyvj网站的逐步壮大,管理员的数目也越来越多,现在你身为Tyvj管理层的联络员,希望你找到一些通信渠道,使得管理员两两都可以联络(直接或者是间接都可以)。本题中所涉及的通信渠道都是 双向 的。
Tyvj是一个公益性的网站,没有过多的利润,所以你要尽可能的使费用少才可以。
目前你已经知道,Tyvj的通信渠道分为两大类,一类是必选通信渠道,无论价格多少,你都需要把所有的都选择上;还有一类是选择性的通信渠道,你可以从中挑选一些作为最终管理员联络的通信渠道。
数据保证给出的通信渠道可以让所有的管理员联通。
注意: 对于某两个管理员u,v,他们之间可能存在多条通信渠道,你的程序应该累加所有u,v之间的必选通行渠道。
#include<bits/stdc++.h> #define N 2010 #define M 10010 using namespace std; struct node { int type,from,to,dis; bool friend operator <(const node &x,const node &y) { return x.dis<y.dis; }; }e[M]; int n,m,fa[N],k,tot; int find(int x) { if(fa[x]==x) return x; return fa[x]=find(fa[x]); } int main() { scanf("%d %d",&n,&m); for(int i=1;i<=n;i++)fa[i]=i; for(int i=1;i<=m;i++) { scanf("%d %d %d %d",&e[i].type,&e[i].from,&e[i].to,&e[i].dis); int type=e[i].type,u=e[i].from,v=e[i].to,d=e[i].dis; if(type==1){tot+=d;if(find(u)!=find(v)){fa[find(u)]=find(v);k++;}} } sort(e+1,e+m+1); for(int i=1;i<=m;i++) { if(k==n-1)break; int type=e[i].type,u=e[i].from,v=e[i].to,d=e[i].dis; if(type==1)continue; if(find(u)!=find(v)){fa[find(u)]=find(v);tot+=d;k++;} } printf("%d\n",tot); return 0; }