1. 程式人生 > >U10206 Cx的治療

U10206 Cx的治療

algorithm 程序 light 嚴重 getchar() 過多 getch true content

題目背景

「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
輸出樣例#2:
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的治療