ccf 最优灌溉

来源:互联网 发布:英语词典哪个好 知乎 编辑:程序博客网 时间:2024/04/28 11:59
一开始 ,看到这个题目,额,最小生成树,然后决定用kruscal ,没想到写完 ,一交 ,20分,开始怀疑人生。

最后发现如果两个集合合并,一定要把根节点合并,两个节点不一定是树,合并后变成什么了。。。。


#include <iostream>#include <queue>#include <algorithm>using namespace std;const int maxn=1005;const int maxe=10000+5;int fa[maxn];int ranke[maxn];struct Edge{int from,to,cost;Edge(int from,int to,int cost):from(from),to(to),cost(cost){}Edge(){}};bool operator <(const Edge & a,const Edge& b){return a.cost>b.cost;}/*bool cmp(const Edge &a ,const Edge &b){return a.cost<b.cost;}*/ int n,m;priority_queue<Edge> s;Edge t[maxe]; // 下面是 并查集模板void init(){for(int i=0;i<=n;i++){    fa[i]=i;    ranke[i]=0;}}int find(int u){ if(u==fa[u]){    return u; }else { return fa[u]=find(fa[u]); //路径压缩 }} void unite(int u,int v){if(find(u)==find(v))return; else { if(ranke[u]>ranke[v]){    fa[v]=u; }else{ fa[u]=v; if(ranke[v]==ranke[u]){    ranke[v]++; } } } } bool issame(int u,int v){     if(find(u)==find(v))return true;     else return false; }void mst(  ){     int  ans=0;     int from,to,cost;     Edge edge;     int cnt=0;while(!s.empty()){       edge=s.top();       s.pop();        from=edge.from;        to=edge.to;        cost=edge.cost;       int u=find(from),v=find(to);       if(issame(from,to))continue;       else{            unite(u,v);    ans+=cost;    cnt++;    if(cnt==n-1){break;}        }     } cout<<ans<<endl; //else cout<<-1<<endl; } int main(){ cin>>n>>m; int from,to,cost; for(int i=0;i<m;i++){    cin>>from>>to>>cost;  s.push(Edge(from,to,cost));}init(); mst(); return 0; }


0 0
原创粉丝点击