zoukankan      html  css  js  c++  java
  • poj2485 kruskal与prim

    Kruskal:



    #include<iostream> #include<cstdio> #include<algorithm> using namespace std; //#define debug #if defined debug #define CDBG(format,...) printf("File: "__FILE__", Line: %05d: "format" ", __LINE__, ##__VA_ARGS__) int open_file(){ FILE *fp ; if((fp = freopen("input3.txt","r",stdin)) == NULL){ CDBG("error in freopen"); return -1; } CDBG("success in freopen"); return 0; } #else #define CDBG(format,...) do{}while(0) #endif #define N 510 int n,k,pre[N]; struct point { int x; int y; int len; }p[N*N]; /*int cmp(const void * x,const void * y) { return ((point*)x)->len>((point*)y)->len?1:-1; }*/ void swap(point &x,point &y) { point temp; temp = x; x = y; y = temp; // 从指针改成数组就行了 } int choose_pivot(int i,int j ) { return((i+j) /2); } void quicksort(point list[],int m,int n) { int key,i,j,k; if( m < n) { k = choose_pivot(m,n);     if(m != k)
    swap(list[m],list[k]); key
    = list[m].len; i = m+1; j = n; while(i <= j) { while((i <= n) && (list[i].len <= key)) i++; while((j >= m) && (list[j].len > key)) j--; if( i < j) swap(list[i],list[j]); } // 交换两个元素的位置     if(m != j)
    swap(list[m],list[j]); // 递归地对较小的数据序列进行排序 quicksort(list,m,j-1); quicksort(list,j+1,n); } } int cmp(point x,point y) { return x.len<y.len; } int find(int x) { while(x!=pre[x]) x=pre[x]; return x; } void kruskal() { int i,mix,a,b; mix=0; //sort(p,p+k,cmp); for(i = 0; i < k ;i++) CDBG("%d ",p[i].len); quicksort(p,0,k-1); //跟 sort 结果完全不一样 for(i = 0; i < k ;i++) CDBG("%d ",p[i].len); for(i=1;i<=n;i++) pre[i]=i;// 可以初始化为 -1 等值 for(i=0;i<k;i++) { a=find(p[i].x); b=find(p[i].y); if(a!=b) { if(p[i].len>mix) mix=p[i].len; pre[b]=a; } } cout<<mix<<endl; } void input() { scanf("%d",&n); k=0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { scanf("%d",&p[k].len); if(i != j && p[k].len != 0){ p[k].x=i; p[k].y=j; k++; //过滤掉ii 点 } } } int main() { int T; #ifdef debug if(open_file() != 0) return -1; #endif scanf("%d",&T); while(T--) { input(); kruskal(); } return 0; }
     void quicksort(int left, int right){
    
        if (left > right)
            return;
        int l = left;
        int r = right+1;
        path v, temp;
        v = ipath[left];
    
        while (1){
            while (l < r && ipath[--r].len >= v.len);
            while (l < r && ipath[++l].len <= v.len);
            if (l >= r) break;
            temp = ipath[l];
            ipath[l] = ipath[r];
            ipath[r] = temp;
        }
    
        ipath[left] = ipath[l];
        ipath[l] = v;
        quicksort(left, l - 1);
        quicksort(l + 1, right);
    }

    Prime:

    参考: http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html
    /*
    题目意思就是求最小生成树,并返回最长edge
    求最小生成树一般有两种方法,prim算法 O[N^2]和kruskal算法 O[ElogE],在这里我推荐使用prim算法,因为此题不是稀疏图,kruskal算法耗时较多(但也不会超时)
    prim算法的基本思想
    1.清空生成树,任取一个顶点加入生成树
    2.在那些一个端点在生成树里,另一个端点不在生成树里的边中,选取一条权最小的边,将它和另一个端点加进生成树
    3.重复步骤2,直到所有的顶点都进入了生成树为止,此时的生成树就是最小生成树
    Prime()
    {
    //开始默认把1加入点集里
    for(2~m)
    dist[i]=map[1][i];
    for(2~m)
    {
    //找跟相连的最短边
    for(2~m)
    {
    if(!visit[j] && dist[j]<inf)
    index="j";
    }=""
    visit[index]="1"
    ;
     根据知道的点更新cost,这里方法有点像dijkstra,注意!!!=""
    for(2~m)="" {="" if(!visit[j]="" &&="" cost[j]="">map[index][j])
    cost[j]=map[index][j];
    }
    }
    }
    */
    #include<stdio.h>    
    #include<string.h>
    
    #define debug
    #if defined debug
    #define CDBG(format,...) printf("File:"__FILE__", Line:%05d: "format"
    ", __LINE__, ##__VA_ARGS__)  
    #else
    #define CDBG(format,...) do{}while(0)
    #endif
    
    #define N 511   
    // n -> [3,500]
    #define inf 0x3f3f3f3f
    //distance -> [1,65536]
    
    int villages[N][N];
    int visited[N];    
    int lowcost[N];
    
    
    int open_file(){
        FILE *fp ;
        if((fp = freopen("input3.txt","r",stdin)) == NULL){
            CDBG("error in freopen");
            return -1;
        }
        CDBG("success in freopen");
        return 0;
    }
    
    void reset_visited(int n){
        int i = 1;
        for( i = 1; i<= n; i++){ visited[i] = 0; lowcost[i] = 0;}
    }
    //下面2个方法都可以
    int prim(int start_p,int n){
        int i,j,pos,min = 0,result = 0;
        reset_visited(n);
        //start at point 1
        visited[start_p] = 1; pos = start_p;
        //set low array from point 1 to other point
        for(i = 1; i <= n; i++)
            if(i != pos) {
                lowcost[i] = villages[pos][i];
                CDBG("set lowcost[%d] = %d",i,lowcost[i]);
            }
        //check n-1 times again , 每次添加一个点到 最小树
        for(i = 1; i < n; i++){ // 使用 while循环代替 for 容易有一些问题
            //find min distance 寻找下一个最短距离
            min = inf;
            for(j = 1; j <= n; j++){
                if(visited[j] == 0 && lowcost[j] < min)
                    {
                        min = lowcost[j];//从未访问的点找到 最短距离的 点
                pos = j; CDBG("min = %d pos = %d j = %d",min,pos,j); } } CDBG("min = %d pos = %d ",min,pos); //add min distance; if(result < min) result = min; // 找最小树的最长距离 visited[pos] = 1; //update 更新当前最小的点 到 所有未访问过的点 的距离 for(j = 1; j <= n; j++){ if(visited[j] == 0 && lowcost[j] > villages[pos][j]) { lowcost[j] = villages[pos][j]; CDBG("update lowcost[%d] = %d",j ,lowcost[j]); } } } return result; } int prim(int n) { int u = 1; int i,j,k,start,min,max; //memset(vis,0,sizeof(vis)); reset_visited(n); for(i=1;i<=n;i++) if(i!=u) lowcost[i]=villages[1][i]; visited[1]=true; k=0; min=0;max=0; for(i=1;i<n;i++) //n-1条边 { min=inf; for(j=1;j<=n;j++) if(lowcost[j]<min&&!visited[j]) { min=lowcost[j]; k=j; } if(min>max) max=min; visited[k]=true; for(j=1;j<=n;j++) if(lowcost[j]>villages[k][j]&&!visited[j]) { lowcost[j]=villages[k][j]; } } return max; //cout<<max<<endl; } void read_villages(int n){ for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) { villages[i][j] = 0; scanf("%d",&villages[i][j]); } } void check_villages(int n){ for(int i = 1; i <= n; i++){ for(int j = 1; j <= n; j++) printf("%d ",villages[i][j]); // 应该是这个导致了 Output Limit Exceeded printf(" "); } } int main(){ int T,n; #ifdef debug if(open_file() != 0) return -1; #endif scanf("%d",&T); while(T--){ scanf("%d",&n); read_villages(n); //check_villages(n); int ans=0; ans = prim(2,n); // 可以从任意一点开始 //ans = prim(n); printf("%d ",ans); } return 0; }
  • 相关阅读:
    poj 2352 Stars(线段树)
    poj 2029 Get Many Persimmon Trees
    .Net remoting 的解答,以及跟WebService的区别
    关于Xcode4.2中的release“不能”使用的理解
    委托的学习日志
    钩子是啥?以及用来说啥,是不是可以用来做即时通讯?
    C#后台程序与HTML页面中JS方法互调(功能类似于Ajax中的DWR)
    接触了一下项目管理系统软件:禅道项目管理软件、Bugfree
    将string变为int 的几种方法方法比较
    Hashtable、Dictionary、SortedDictionary、SortedList的比较应用
  • 原文地址:https://www.cnblogs.com/Pitter99/p/4795668.html
Copyright © 2011-2022 走看看