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。
輸入輸出樣例
輸入樣例#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:
-1輸入樣例#2:
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; }
U10206 Cx的治療