cf17B 建树,使得边之和最小 (水题)


要建立一颗树,使得树的边sum最小,同时判断是否能生成一颗树..


Nick's company employed n people. Now Nick needs to build a tree hierarchy of «supervisor-surbodinate» relations in the company (this is to say that each employee, except one, has exactly one supervisor). There are m applications written in the following form: «employeeai is ready to become a supervisor of employee bi at extra cost ci». The qualification qj of each employee is known, and for each application the following is true: qai > qbi.

Would you help Nick calculate the minimum cost of such a hierarchy, or find out that it is impossible to build it.

Input

The first input line contains integer n (1 ≤ n ≤ 1000) — amount of employees in the company. The following line contains n space-separated numbers qj (0 ≤ qj ≤ 106)— the employees' qualifications. The following line contains number m (0 ≤ m ≤ 10000) — amount of received applications. The following m lines contain the applications themselves, each of them in the form of three space-separated numbers: aibi and ci (1 ≤ ai, bi ≤ n0 ≤ ci ≤ 106). Different applications can be similar, i.e. they can come from one and the same employee who offered to become a supervisor of the same person but at a different cost. For each application qai > qbi.

Output

Output the only line — the minimum cost of building such a hierarchy, or -1 if it is impossible to build it.

Sample Input

Input
4
7 2 3 1
4
1 2 5
2 4 1
3 4 1
1 3 5
Output
11
Input
3
1 2 3
2
3 1 2
3 1 3
Output
-1

Hint

In the first sample one of the possible ways for building a hierarchy is to take applications with indexes 1, 2 and 4, which give 11 as the minimum total cost. In the second sample it is impossible to build the required hierarchy, so the answer is -1.



my code:

#include<bits/stdc++.h>
using namespace std;
const int N = 1111;
const int inf = 0x3f3f3f3f;
int fa[N],a[N];
struct node
{
	int x;
	int r;
};
vector<node>vv[N];
int find(int x)
{
	int r=x;
	while(fa[r]!=r) r=fa[r];
	int i=x,j;
	while(i!=r) {
		j=fa[i];
		fa[i]=r;
		i=j;
	}
	return r;
}

int main()
{
	int n,i,j,ans,m,y,tem,index;
	int fx,fy;
	node t;
	cin>>n;
	for(i=1;i<=n;i++) {
		fa[i]=i;
		cin>>a[i];
	}
	cin>>m;
	while(m--) {
		cin>>t.x>>y>>t.r;
		if(a[t.x]>a[y]) vv[y].push_back(t);
	}
	ans=0;
	for(i=1;i<=n;i++) {
		tem=inf;index=i;
		for(j=0;j<vv[i].size();j++) {
			t=vv[i][j];
			if(t.r<tem) {
				tem=t.r;
				index=t.x;
			}
		}
		fx=find(i);
		fy=find(index);
		if(fx!=fy) {
			fa[fx]=fy;
			ans+=tem;
		}
	}
	for(i=2;i<=n;i++) {
		if(find(1)!=find(i)) break;
	}
	if(i>n) cout<<ans<<endl;
	else cout<<"-1"<<endl;
	return 0;
}


大神的code: ORZ


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>

#define REP(AA,BB) for(int AA=0; AA<(BB); ++AA)
#define FOR(AA,BB,CC) for(int AA=(BB); AA<(CC); ++AA)
#define FC(AA,BB) for(__typeof((AA).begin()) BB=(AA).begin(); BB!=(AA).end(); ++BB)
#define SZ(AA) ((int)((AA).size()))
#define ALL(AA) (AA).begin(), (AA).end()
#define PB push_back
#define MP make_pair

using namespace std;

typedef vector<int> VI;
typedef pair<int, int> PII;
typedef long long LL;
typedef long double LD;

const int MAXN = 1010;
int best[MAXN], INF = 1000000000;

int main(void) {
    int n; scanf("%d", &n);
    REP (i, n) {
        scanf("%*d");
        best[i] = INF;
    }
    int m; scanf("%d", &m);
    REP (i, m) {
        int a, b, c; scanf("%d%d%d", &a, &b, &c);
        --a; --b;
        best[b] = min(best[b], c);
    }
    int inf_count = 0, res = 0;
    REP (i, n) {
        if (best[i] == INF) {
            ++inf_count;
        } else {
            res += best[i];
        }
    }
    if (inf_count != 1) {
        puts("-1");
    } else {
        printf("%d\n", res);
    }
    return 0;
}






你可能感兴趣的:(cf17B 建树,使得边之和最小 (水题))