U10206 Cx的治疗
「Cx的故事」众所周知,Cx是一个宇宙大犇。由于Cx在空中花园失足摔下,导致他那蕴含着无穷智慧的大脑受到了严重的损伤,许多的脑神经断裂。于是,Cx的wife(有么?)决定请巴比伦最好的医师治疗。但是,Cx的wife是个十分吝啬的人,虽然她想将Cx治好,但是她又不肯出过多的钱,而脑神经的重新连接需要大量的花费。所以,当她知道来自未来的你时,她恳求你去帮她计算一下如何才能将Cx的神经元全部重新连接起来,而花费最小。
题目描述
神经网络就是一张无向图,图中的节点称为神经元,神经元已经按照1~N的顺序排好号,而且两个神经元之间至多有一条脑神经连接。
现有N个神经元,M条仍然完好的脑神经,连接神经元Ai与Bi。
医生给出能够连接的t条脑神经,分别连接神经元Aj与Bj,并给出连接所需的花费Ci。
请编写程序计算将所有神经元连通的最小花费w。
输入输出格式
输入格式:
第一行为两个整数N,M (1<=N<=10000,1<=M<=100000) 表示一共有N个神经元,有M条依旧完好的脑神经。
接下来M行每行有两个整数Ai,Bi (1<=Ai,Bi<=10000) 表示神经元Ai,Bi已经连在一起。
接下来一行有一个整数t (1<=t<=10000)表示医生能连接的神经个数。
接下来t 行有三个整数 Aj ,Bj ,Cj (1<=Ai,Bi,Cj<=10000) 表示神经元Aj,Bj能通过Cj的花费将其连在一起。
输出格式:
仅一行,为一个整数,表示将Cx的神经元连通起来的最小花费w。若不能将其全部连通,请输出-1。
输入输出样例
10 5 1 5 2 6 3 7 3 8 3 9 10 2 4 10 3 6 15 2 4 9 2 6 34 5 7 64 2 8 26 3 7 16 5 2 7 3 9 13 8 5 12
-1
10 5 1 5 2 6 3 7 3 8 3 9 10 8 10 10 3 6 15 2 4 9 2 6 34 5 7 64 2 8 26 3 7 16 5 2 7 3 9 13 8 5 12
38
说明
1<=N<=10000,0<=M<=100000;
1<=Ai,Bi,Aj,Bj<=10000;
1<=Cj<=100000;
1<=t<=100000;
写程序有时也需要运气的:N=10010 MLE,N=7010 RE, N=7510/8510 RE,N=9510 AC
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; const int N=9510; struct node{ int u,v,w; }E[N*1000]; int n,m,t,tot; int l,r; long long answer; int f[N]; inline int read() { int x=0;char c=getchar(); while(c<'0'||c>'9')c=getchar(); while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar(); return x; } int getfa(int x) { return f[x]==x?x:f[x]=getfa(f[x]); } inline bool cmp(node a,node b) { return a.w<b.w; } int main() { n=read(); m=read(); for(int i=1;i<=n;i++) f[i]=i; for(int i=1;i<=m;i++) { l=read(); r=read(); int fl=getfa(l); int fr=getfa(r); if(fl!=fr) f[fl]=fr,tot++; } t=read(); for(int i=1;i<=t;i++) E[i].u=read(), E[i].v=read(), E[i].w=read(); sort(E+1,E+t+1,cmp); int total=0; for(int i=1;i<=t;i++) { int fu=getfa(E[i].u); int fv=getfa(E[i].v); if(fu!=fv) { f[fu]=fv; answer+=E[i].w; total++; } if(total==(n-1-tot)) { printf("%lld",answer); return 0; } } printf("-1"); return 0; }