zoukankan      html  css  js  c++  java
  • 生成树模板总结

    首先来发模板 poj 1287

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    
    using namespace std;
    const int maxn=1010;
    const int INF=0x3f3f3f3f;
    struct Node{
        double x,y,h;
    }point[maxn];
    double mat[maxn][maxn];
    double h[maxn][maxn];
    double l[maxn][maxn];
    int n;
    double head,tail;
    
    double dist(Node &a,Node &b)
    {
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    
    double prim()
    {
        double ans=0.0,Min;
        int vis[maxn];double dis[maxn];
        for(int i=0;i<n;i++){
            dis[i]=mat[0][i];
            vis[i]=0;
        }
        dis[0]=1;
        vis[0]=1;
        for(int l=1;l<n;l++){
            Min=INF;int pos=-1;
            for(int i=0;i<n;i++){
                if(!vis[i]&&dis[i]<Min){
                    Min=dis[i];
                    pos=i;
                }
            }
            vis[pos]=1;
            ans+=Min;
            for(int i=0;i<n;i++){
                if(!vis[i]&&dis[i]>mat[pos][i]){
                    dis[i]=mat[pos][i];
                }
            }
        }
        return ans;
    }
    int main()
    {
        int i,j;
        double maxc,minc,maxl,minl,mid;
        while(scanf("%d",&n)&&n)
        {
            maxc=-INF;
            minc=INF;
            maxl=-INF;
            minl=INF;
            for(i=0;i<n;i++)
            scanf("%lf%lf%lf",&point[i].x,&point[i].y,&point[i].h);
            for(i=0;i<n-1;i++)
            for(j=i+1;j<n;j++)
            {
                h[i][j]=h[j][i]=fabs(point[i].h-point[j].h);
                l[i][j]=l[j][i]=dist(point[i],point[j]);
                if(maxc<h[i][j])
                maxc=h[i][j];
                if(minc>h[i][j])
                minc=h[i][j];
                if(maxl<l[i][j])
                maxl=l[i][j];
                if(minl>l[i][j])
                minl=l[i][j];
            }
            head=minc/maxl;
            tail=maxc/minl;
            while(tail-head>1e-4)
            {
                mid=(head+tail)/2;
                for(i=0;i<n-1;i++)
                for(j=i+1;j<n;j++)
                mat[i][j]=mat[j][i]=h[i][j]-mid*l[i][j];
                if(prim()<=0.0)
                tail=mid;
                else
                head=mid;
            }
            printf("%.3f
    ",head);
        }
        return 0;
    }
    
    

    然后来发次小生成树的模板 poj 1679

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    const int maxn=10010;
    int f[maxn],mst[maxn];
    int n,m,t;
    struct V
    {
        int u,v,l;
    } a[maxn];
    
    int sf(int x)
    {
        return x==f[x]?f[x]:f[x]=sf(f[x]);
    }
    
    int cmp(V a,V b)
    {
        return a.l<b.l;
    }
    
    void kruskal()
    {
        int cnt=n-1;
        int ant=n-1;
        int res1=0;
        int res2=0;
        for(int i=0; i<=n; i++)f[i]=i;
        sort(a,a+m,cmp);
        for(int i=0; i<m&&ant; i++)
        {
            if(sf(a[i].u)!=sf(a[i].v))
            {
                f[sf(a[i].u)]=sf(a[i].v);
                res1+=a[i].l;
                ant--;
                mst[ant]=i;
            }
        }
        for(int i=0; i<n-1; i++)
        {
            ant=n-1;
            res2=0;
            for(int j=0; j<=n; j++)f[j]=j;
            for(int j=0; j<m&&ant; j++)
            {
                if(j==mst[i])continue;
                if(sf(a[j].u)!=sf(a[j].v))
                {
                    f[sf(a[j].u)]=sf(a[j].v);
                    res2+=a[j].l;
                    ant--;
                }
            }
            //cout<<"2.---"<<ant<<"---"<<res2<<endl;
            if(ant!=0)continue;
            if(res1==res2){
                printf("Not Unique!
    ");
                return;
            }
        }
        cout<<res1<<endl;
    }
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            for(int i=0; i<m; i++)
                scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].l);
            kruskal();
        }
    }
    
    

    再来发最小树形图模板 Poj3164

    /*
    ID: CUGB-wwj
    PROG:
    LANG: C++
    */
    #include <iostream>
    #include <vector>
    #include <list>
    #include <map>
    #include <set>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <bitset>
    #include <algorithm>
    #include <functional>
    #include <numeric>
    #include <utility>
    #include <sstream>
    #include <iomanip>
    #include <cstdio>
    #include <cmath>
    #include <cstdlib>
    #include <cctype>
    #include <string>
    #include <cstring>
    #include <cmath>
    #include <ctime>
    #define INF 2000000000
    #define MAXN 105
    #define MAXM 1005
    #define L(x) x<<1
    #define R(x) x<<1|1
    #define eps 1e-4
    using namespace std;
    typedef double type;
    struct Point
    {
        double x, y;
    }p[MAXN];
    struct node
    {
        int u, v;
        type w;
    }edge[MAXN * MAXN];
    int pre[MAXN], id[MAXN], vis[MAXN], n, m;
    type in[MAXN];
    double dis(Point a, Point b)
    {
        return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
    }
    type Directed_MST(int root, int V, int E)
    {
        type ret = 0;
        while(true)
        {
            //1.找最小入边
            for(int i = 0; i < V; i++) in[i] = INF;
            for(int i = 0; i < E; i++)
            {
                int u = edge[i].u;
                int v = edge[i].v;
                if(edge[i].w < in[v] && u != v) {pre[v] = u; in[v] = edge[i].w;}
            }
            for(int i = 0; i < V; i++)
            {
                if(i == root) continue;
                if(in[i] == INF) return -1;//除了跟以外有点没有入边,则根无法到达它
            }
            //2.找环
            int cnt = 0;
            memset(id, -1, sizeof(id));
            memset(vis, -1, sizeof(vis));
            in[root] = 0;
            for(int i = 0; i < V; i++) //标记每个环
            {
                ret += in[i];
                int v = i;
                while(vis[v] != i && id[v] == -1 && v != root)  //每个点寻找其前序点,要么最终寻找至根部,要么找到一个环
                {
                    vis[v] = i;
                    v = pre[v];
                }
                if(v != root && id[v] == -1)//缩点
                {
                    for(int u = pre[v]; u != v; u = pre[u]) id[u] = cnt;
                    id[v] = cnt++;
                }
            }
            if(cnt == 0) break; //无环   则break
            for(int i = 0; i < V; i++)
                if(id[i] == -1) id[i] = cnt++;
                  //3.建立新图
            for(int i = 0; i < E; i++)
            {
                int u = edge[i].u;
                int v = edge[i].v;
                edge[i].u = id[u];
                edge[i].v = id[v];
                if(id[u] != id[v]) edge[i].w -= in[v];
            }
            V = cnt;
            root = id[root];
        }
        return ret;
    }
    int main()
    {
        while(scanf("%d%d", &n, &m) != EOF)
        {
            for(int i = 0; i < n; i++) scanf("%lf%lf", &p[i].x, &p[i].y);
            for(int i = 0; i < m; i++)
            {
                scanf("%d%d", &edge[i].u, &edge[i].v);
                edge[i].u--;
                edge[i].v--;
                if(edge[i].u != edge[i].v) edge[i].w = dis(p[edge[i].u], p[edge[i].v]);
                else edge[i].w = INF; //去除自环
            }
            type ans = Directed_MST(0, n, m);
            if(ans == -1) printf("poor snoopy
    ");
            else printf("%.2f
    ", ans);
        }
        return 0;
    }
    

    最后是最小K度生成树

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<map>
    #include<queue>
    #include<algorithm>
    #include<climits>
    using namespace std;
    map<string,int> mp;
    int m,n,k;
    int g[30][30],dis[30],clo[30],pre[30],fst[30],max_side[30];
    const int inf=1000010000;
    struct node
    {
        int v,cap;
        node(){}
        node(int _v,int _cap):v(_v),cap(_cap){}
        bool operator < (const node &dd) const
        {
            return cap>dd.cap;
        }
    };
    int prim(int src,int id)
    {
        priority_queue<node> q;
        while(!q.empty()) q.pop();
        dis[src]=0;
        q.push(node(src,0));
        int ans=0;
        while(!q.empty())
        {
            node cur=q.top();
            q.pop();
            int u=cur.v;
            if(!clo[u])
            {
                clo[u]=id;
                ans+=dis[u];
                for(int i=1;i<n;i++)
                {
                    if(!clo[i]&&g[u][i]!=0&&dis[i]>g[u][i])
                    {
                        pre[i]=u;
                        dis[i]=g[u][i];
                        q.push(node(i,dis[i]));
                    }
                }
            }
        }
        return ans;
    }
    void update(int cur,int last,int maxside)
    {
        max_side[cur]=maxside>g[cur][last]?maxside:g[cur][last];
        for(int i=1;i<n;i++)
        {
            if(i!=last&&g[cur][i]!=0&&(pre[cur]==i||pre[i]==cur))
                update(i,cur,max_side[cur]);
        }
    }
    void solve()
    {
        for(int i=0;i<n;i++)
        {
            dis[i]=inf;
            clo[i]=pre[i]=fst[i]=0;
        }
        int res=0,cnt=1;
        for(int i=1;i<n;i++)
        {
            if(!clo[i])
                res+=prim(i,cnt++);
        }
        for(int i=1;i<n;i++)
        {
            int id=clo[i];
            if(g[0][i]!=0&&(!fst[id]||g[0][i]<g[0][fst[id]]))
                fst[id]=i;
        }
        for(int i=1;i<cnt;i++)
        {
            res+=g[0][fst[i]];
            g[0][fst[i]]=g[fst[i]][0]=0;
            update(fst[i],0,0);
        }
        k=k-cnt+1;
        while(k--)
        {
            int tmp=0;
            for(int i=1;i<n;i++)//kdjfke
            {
                if(g[0][i]&&(tmp==0||max_side[tmp]-g[0][tmp]<max_side[i]-g[0][i]))
                    tmp=i;
            }
            if(max_side[tmp]<=g[0][tmp])
                break;
            res=res-max_side[tmp]+g[0][tmp];
            g[0][tmp]=g[tmp][0]=0;
            int p=0;
            for(int i=tmp;pre[i]!=0;i=pre[i])
            {
                if(p==0||g[p][pre[p]]<g[i][pre[i]])
                    p=i;
            }
            pre[p]=0;
            update(tmp,0,0);
        }
        printf("Total miles driven: %d
    ",res);
    }
    int main()
    {
        char s1[20],s2[20];
        int cap;
        while(scanf("%d",&m)!=EOF&&m!=0)
        {
            mp.clear();
            n=1;
            memset(g,0,sizeof(g));
            mp["Park"]=0;
            while(m--)
            {
                scanf("%s %s %d",s1,s2,&cap);
                if(!mp.count(s1)) mp[s1]=n++;
                if(!mp.count(s2)) mp[s2]=n++;
                int u=mp[s1],v=mp[s2];
                if(!g[u][v]||cap<g[u][v])
                    g[u][v]=g[v][u]=cap;
            }
            scanf("%d",&k);
            solve();
        }
        return 0;
    }
    
  • 相关阅读:
    如果有一天,有个人递过来一支唇油,然后对我说:嘿,弄下你那难受又难看的唇吧!然后我会倾我一生去待这个...
    linux下使用masm通过dosemu及freedos
    回复草儿:呵呵~~嗯在firefox下的展示还不是特别好,有些页面显示不了。叫这个名字的人好像很多哦...
    firefox显示不了QQ空间日志内容的临时解决方法
    语法分析:算术表达式预测分析程序设计
    哈哈,那就找个同名的美女来段美丽传说~链接已做好。
    现在QQ空间不是已经支持其他浏览器的么,昨天我还在linux下用opera看朋友的QQ空间呢。PS:...
    【SQL SERVER】Sql语句使用技巧 优化数据库
    从IL认识关键字(四)
    从IL认识关键字(三)
  • 原文地址:https://www.cnblogs.com/wlxtuacm/p/5708746.html
Copyright © 2011-2022 走看看