• POJ1358 Agri-Net


    题目链接

    就是裸的最小生成树,复习一下。

    prim算法:

    G=(V,E),V是点集,E是边集

    假设T=(U,TE)是最小生成树。U,TE初始化为空

    首先从V中任取一点 假设取V1,然后U={V1},只要U是V的真子集,就从那些一个端点在T中,一个端点在T外的边中,找一条最短边。一直下去,直到找到n-1条边

    找边使用 堆优化,复杂度(ElogV) 邻接表复杂度(V2

     1 #include<cstdio>
     2 #include<vector>
     3 #include<queue>
     4 #include<cstring>
     5 using namespace std;
     6 const int maxn=110;
     7 const int inf=0x3f3f3f3f;
     8 
     9 struct node{
    10     int v,dis;
    11     node(){}
    12     node(int _v,int _dis){
    13         v=_v;
    14         dis=_dis;
    15     }
    16     bool operator<(const node &b) const {
    17         return dis>b.dis;
    18     }
    19 };
    20 
    21 int n,dis[maxn];
    22 vector<node> G[maxn];
    23 bool vis[maxn];
    24 
    25 void prim() {
    26     int ans=0,num=0;
    27     priority_queue<node> pq;
    28     for(int i=0;i<n;i++) {
    29         vis[i]=false;
    30         dis[i]=inf;
    31     }
    32     pq.push(node(0,0));
    33     node f;
    34     while(num<n&&!pq.empty()) {
    35         do{
    36            f=pq.top();
    37            pq.pop();
    38         }while(vis[f.v]&&!pq.empty());
    39         if(!vis[f.v]) {
    40             ans+=f.dis;
    41             vis[f.v]=true;
    42             num++;
    43             for(int i=0;i<G[f.v].size();i++) {
    44                 int v=G[f.v][i].v;
    45                 if(!vis[v]) {
    46                     if(dis[v]>G[f.v][i].dis) {
    47                         dis[v]=G[f.v][i].dis;
    48                         pq.push(node(v,dis[v]));
    49                     }
    50                 }
    51             }
    52         }
    53     }
    54     if(num<n) printf("-1
    ");//因为这里记录的是点的个数。不是边
    55     else printf("%d
    ",ans);
    56 }
    57 
    58 int main() {
    59     while(~scanf("%d",&n)) {
    60         memset(G,0,sizeof(G));
    61         for(int i=0;i<n;i++) {
    62             for(int j=0;j<n;j++) {
    63                 int x;
    64                 scanf("%d",&x);
    65                 if(x) G[i].push_back(node(j,x));
    66             }
    67         }
    68         prim();
    69     }
    70 }

    krusual算法:

    将图G中的边按权值从小到大选取,使选取的不与生成树构成回路。直到n-1条边为止

    判断回路就用并查集搞一下。

     1 #include<cstdio>
     2 #include<vector>
     3 #include<queue>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 const int maxn=110;
     8 const int inf=0x3f3f3f3f;
     9 
    10 int n;
    11 struct Edge{
    12     int u,v,dis;
    13     Edge(){}
    14     Edge(int _u,int _v,int _dis) {
    15         u=_u;
    16         v=_v;
    17         dis=_dis;
    18     }
    19     bool operator <(const Edge &b) const {
    20         return dis<b.dis;
    21     }
    22 };
    23 
    24 vector<Edge> edge;
    25 
    26 int fa[maxn];
    27 
    28 int Find(int x) {
    29     if(fa[x]==-1) return x;
    30     else return fa[x]=Find(fa[x]);
    31 }
    32 
    33 void Union(int x,int y) {
    34     int fx=Find(x);
    35     int fy=Find(y);
    36     if(fx!=fy) {
    37         fa[fx]=fy;
    38     }
    39 }
    40 
    41 int main() {
    42     while(~scanf("%d",&n)) {
    43         memset(fa,-1,sizeof(fa));
    44         edge.clear();
    45         for(int i=0;i<n;i++) {
    46             for(int j=0;j<n;j++) {
    47                 int x;
    48                 scanf("%d",&x);
    49                 if(x&&j<i) edge.push_back(Edge(i,j,x));
    50             }
    51         }
    52         sort(edge.begin(),edge.end());
    53         int num=0,ans=0;
    54         for(int i=0;i<edge.size();i++) {
    55             int u=edge[i].u,v=edge[i].v,dis=edge[i].dis;
    56             if(Find(u)!=Find(v)) {
    57                 num++;
    58                 ans+=dis;
    59                 Union(u,v);
    60             }
    61         }
    62         if(num==n-1) printf("%d
    ",ans);
    63         else printf("-1
    ");
    64     }
    65 }
  • 相关阅读:
    学习笔记(5)——实验室集群LVS监控Web界面配置
    学习笔记(4)——实验室集群管理结点IP配置
    Java中List集合去除重复数据的方法
    Android App内部自动更新Library的使用(转载)
    AppBarLayout+TabLayout+RecyclerView+ViewPager+Fragment(布局悬浮)
    126、android html唤醒APP(转载)
    第三方免费加固横向对比(转载)
    124、@JavascriptInterface
    123、 android Retrofit 介绍和使用(转载)
    win10专业版激活步骤
  • 原文地址:https://www.cnblogs.com/ACMerszl/p/10667146.html
Copyright © 2020-2023  润新知