poj2485 kruskal与prim

Prime:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

#define debug
#if defined debug
#define CDBG(format,...) printf("File: "__FILE__", Line: %05d: "format"\n", __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;
    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;
}

Kruskal:

#include<stdio.h>
#include<string.h>

#define debug
#if defined debug
#define CDBG(format,...) printf("File:"__FILE__", Line:%05d: "format"\n", __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("\n");
    }
}
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\n",ans);
    }

    return 0;
}    
时间: 2024-12-25 23:48:38

poj2485 kruskal与prim的相关文章

HDU 1233 还是畅通工程 ( Kruskal或Prim)

还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 29411    Accepted Submission(s): 13156 Problem Description 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能

最小生成树(kruskal模版 Prim模板)

http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2144&cid=1186 最小生成树,最重要的是了解思想 稠密图用Prim,稀疏图用Kruskal K(每次找最小的边连接,一条边连接两个点,所以单路就可以了) 1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 int bin[110]; 5 struct node 6 { 7 int

HDU 1102 最小生成树裸题,kruskal,prim

1.HDU  1102  Constructing Roads    最小生成树 2.总结: 题意:修路,裸题 (1)kruskal //kruskal #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<cstdio> #define max(a,b) a>b?a:b using na

算法导论--最小生成树(Kruskal和Prim算法)

转载请注明出处:勿在浮沙筑高台http://blog.csdn.net/luoshixian099/article/details/51908175 关于图的几个概念定义: 连通图:在无向图中,若任意两个顶点vi与vj都有路径相通,则称该无向图为连通图. 强连通图:在有向图中,若任意两个顶点vi与vj都有路径相通,则称该有向图为强连通图. 连通网:在连通图中,若图的边具有一定的意义,每一条边都对应着一个数,称为权:权代表着连接连个顶点的代价,称这种连通图叫做连通网. 生成树:一个连通图的生成树是

HDU 1233 还是畅通工程【最小生成树入门题,Kruskal算法+Prim算法】

还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 39929    Accepted Submission(s): 18144 Problem Description 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路

稀疏图(邻接链表),并查集,最短路径(Dijkstra,spfa),最小生成树(kruskal,prim)

#include<iostream> #include<vector> #include<queue> #include<stack> #include<algorithm> #include<stdio.h> #include<stdlib.h> using namespace std; /* //函数集合声明下,方便查看 void Dijkstra(const denseGraph& dg, int s); v

POJ2485 Highways【Prim】

Highways Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 23247 Accepted: 10720 Description The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has no public highways. So the traffic is difficult in Flatopia. The Flatop

poj2485(Kruskal)

这道题显然是一道最小生成树的问题,参考算法导论中的Kruskal方法,先对路径长度进行排序,然后使用并查集(Disjoint Set Union)来判断节点是否连通,记录连接所有节点的最后一条路径的长度即为最大的长度了. 下面的并查集算法还可以通过设置rank数组记录节点的等级来进一步优化.总的来说还是一道简单题. #include <cstdio> #include <algorithm> using namespace std; struct Edge{ int x, y; i

转 最小生成树(kruskal 算法 和prim算法)

链接:http://blog.csdn.net/weinierbian/article/details/8059129/ 给定一个带权的无向连通图,如何选取一棵生成树,使树上所有边上权的总和为最小,这叫最小生成树. 求最小生成树的算法(1) 克鲁斯卡尔算法图的存贮结构采用边集数组,且权值相等的边在数组中排列次序可以是任意的.该方法对于边相对比较多的不是很实用,浪费时间.(2) 普里姆算法图的存贮结构采用邻接矩阵.此方法是按各个顶点连通的步骤进行,需要用一个顶点集合,开始为空集,以后将以连通的顶点