[USACO08NOV]安慰奶牛Cheering up the Cow BZOJ 1232 Kruskal
Farmer John變得非常懶, 他不想再繼續維護供奶牛之間供通行的道路. 道路被用來連線N (5 <= N <= 10,000)個牧場, 牧場被連續地編號為1..N. 每一個牧場都是一個奶牛的家. FJ計劃除去P(N-1 <= P <= 100,000)條道路中儘可能多的道路, 但是還要保持牧場之間的連通性. 你首先要決定那些道路是需要保留的N-1條道路. 第j條雙向道路連線了牧場S_j和E_j (1 <= S_j <= N; 1 <= E_j <= N; S_j != E_j), 而且走完它需要L_j (0 <= L_j <= 1,000)的時間. 沒有兩個牧場是被一條以上的道路所連線. 奶牛們非常傷心, 因為她們的交通系統被削減了. 你需要到每一個奶牛的住處去安慰她們. 每次你到達第i個牧場的時候(即使你已經到過), 你必須花去C_i (1 <= C_i <= 1,000)的時間和奶牛交談. 你每個晚上都會在同一個牧場(這是供你選擇的)過夜, 直到奶牛們都從悲傷中緩過神來. 在早上起來和晚上回去睡覺的時候, 你都需要和在你睡覺的牧場的奶牛交談一次. 這樣你才能完成你的交談任務. 假設Farmer John採納了你的建議, 請計算出使所有奶牛都被安慰的最少時間. 對於你前10次的提交, 你的程式會在一部分正式的測試資料上執行, 並且返回執行的結果.
Sample Output176 Hint
Input
* 第 1 行: 用空格隔開的兩個整數N和P * 第 2..N+1 行: 第i+1行包含了一個整數: C_i * 第 N+2..N+P+1 行: 第 N+j+1 行包含用空格隔開的三個整數: S_j, E_j 和 L_j
Output第 1 行: 一個整數, 所需要的總時間(包含和在你所在的牧場的奶牛的兩次談話時間).
Sample Input 5 7 10 10 20 6 30 1 2 5 2 3 5 2 4 12 3 4 17 2 5 15 3 5 6 4 5 12 感覺自己語文太差,題目剛開始沒怎麼讀懂.........#include<iostream> #include<cstdio> #include<algorithm> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #include<set> #include<vector> #include<queue> #include<bitset> #include<ctime> #include<deque> #include<stack> #include<functional> #include<sstream> //#include<cctype> //#pragma GCC optimize("O3") using namespace std; #define maxn 200005 #define inf 0x3f3f3f3f #define INF 9999999999 #define rdint(x) scanf("%d",&x) #define rdllt(x) scanf("%lld",&x) #define rdult(x) scanf("%lu",&x) #define rdlf(x) scanf("%lf",&x) #define rdstr(x) scanf("%s",x) typedef long long ll; typedef unsigned long long ull; typedef unsigned int U; #define ms(x) memset((x),0,sizeof(x)) const long long int mod = 1e9 + 7; #define Mod 1000000000 #define sq(x) (x)*(x) #define eps 1e-3 typedef pair<int, int> pii; #define pi acos(-1.0) const int N = 1005; #define REP(i,n) for(int i=0;i<(n);i++) typedef pair<int, int> pii; inline ll rd() { ll x = 0; char c = getchar(); bool f = false; while (!isdigit(c)) { if (c == '-') f = true; c = getchar(); } while (isdigit(c)) { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } return f ? -x : x; } ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a%b); } ll sqr(ll x) { return x * x; } /*ll ans; ll exgcd(ll a, ll b, ll &x, ll &y) { if (!b) { x = 1; y = 0; return a; } ans = exgcd(b, a%b, x, y); ll t = x; x = y; y = t - a / b * y; return ans; } */ ll qpow(ll a, ll b, ll c) { ll ans = 1; a = a % c; while (b) { if (b % 2)ans = ans * a%c; b /= 2; a = a * a%c; } return ans; } int n, m; struct node { int u, v, w; }edge[maxn]; int valnode[maxn]; bool cmp(node a, node b) { return a.w < b.w; } int tot; int fa[maxn]; int findfa(int x) { if (x == fa[x])return x; return fa[x] = findfa(fa[x]); } int kruskal() { int ans = 0; for (int i = 0; i <= n; i++)fa[i] = i; sort(edge , edge + tot, cmp); int cnt = 0; for (int i = 0; i < tot; i++) { int u = edge[i].u; int v = edge[i].v; int w = edge[i].w; if (findfa(u) != findfa(v)) { fa[findfa(u)] = findfa(v); ans += w; cnt++; if (cnt == n - 1)break; } } return ans; } void addedge(int u, int v, int w) { edge[tot].u = u; edge[tot].v = v; edge[tot++].w = w * 2 + valnode[u] + valnode[v]; } int main() { //ios::sync_with_stdio(0); rdint(n); rdint(m); int minn = inf; for (int i = 1; i <= n; i++)rdint(valnode[i]), minn = min(minn, valnode[i]); for (int i = 1; i <= m; i++) { int u, v, w; rdint(u); rdint(v); rdint(w); addedge(u, v, w); addedge(v, u, w); } cout << kruskal()+minn << endl; return 0; }