BZOJ1601: [Usaco2008 Oct]灌水
最小生成树
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #define pb push_back #define MAXN 300+10 using namespace std; struct Edge{ int from,to,cost; Edge(int x=0,int y=0,int c=0){ from=x,to=y,cost=c; } friend bool operator < (const Edge &p1,const Edge &p2){ return (p1.cost<p2.cost); } }; vector<Edge> vs; int n; int f[MAXN]; int find(int x){ return (f[x]==x?x:f[x]=find(f[x])); } void lik(int x,int y){ x=find(x),y=find(y); if(x!=y){ f[x]=y; } } bool same(int x,int y){ return (find(x)==find(y)); } void init(){ scanf("%d",&n); for(int i=1;i<=n;i++){ int v;scanf("%d",&v); vs.pb(Edge(0,i,v)); } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ int v;scanf("%d",&v); if(i<=j)continue; vs.push_back(Edge(i,j,v)); } } for(int i=1;i<=n;i++){ f[i]=i; } } void solve(){ sort(vs.begin(),vs.end()); int ans=0; for(int i=0;i<vs.size();i++){ int x=vs[i].from,y=vs[i].to,c=vs[i].cost; if(!same(x,y)){ lik(x,y); ans+=c; } } printf("%d\n",ans); } int main() { init(); solve(); return 0; }