[BZOJ 1232]安慰奶牛
转载请注明出处:http://danihao123.is-programmer.com/
这题要用到DFS欧拉遍历树(胡编词汇)的一个特征:每一条边都经过2遍。这样似乎每个边度数就可以确定了,然后……
但是,起点也要算啊……
代码:
/************************************************************** Problem: 1232 User: danihao123 Language: C++ Result: Accepted Time:248 ms Memory:2056 kb ****************************************************************/ #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=10001,maxm=100001; // Djoin set int p[maxn]; int find_set(int x){ if(p[x]==x) return x; else return p[x]=find_set(p[x]); } void union_set(int x,int y){ p[find_set(x)]=find_set(y); } bool is_same(int x,int y){ return find_set(x)==find_set(y); } // Graph struct Edge{ int u,v,d; }; int cmp(const Edge& a,const Edge& b){ return a.d<b.d; } int n,m; int c[maxn]; Edge E[maxm]; int mst(){ register int i,cnt=0,ans=0; for(i=1;i<=n;i++) p[i]=i; sort(E,E+m,cmp); for(i=0;cnt<(n-1) && i<m;i++){ if(!is_same(E[i].u,E[i].v)){ union_set(E[i].u,E[i].v); ans+=E[i].d; cnt++; } } return ans; } int main(){ register int i,kkk=0x5fffffff; scanf("%d%d",&n,&m); for(i=1;i<=n;i++){ scanf("%d",&c[i]); kkk=min(kkk,c[i]); } for(i=0;i<m;i++){ scanf("%d%d%d",&E[i].u,&E[i].v,&E[i].d); E[i].d+=E[i].d+c[E[i].u]+c[E[i].v]; } printf("%d\n",kkk+mst()); return 0; }