POJ 2485 Highways 最小生成樹 Kruskal && Prim


Highways
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 25027   Accepted: 11548

Description

The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has no public highways. So the traffic is difficult in Flatopia. The Flatopian government is aware of this problem. They're planning to build some highways so that it will be possible to drive between any pair of towns without leaving the highway system. 

Flatopian towns are numbered from 1 to N. Each highway connects exactly two towns. All highways follow straight lines. All highways can be used in both directions. Highways can freely cross each other, but a driver can only switch between highways at a town that is located at the end of both highways. 

The Flatopian government wants to minimize the length of the longest highway to be built. However, they want to guarantee that every town is highway-reachable from every other town.

Input

The first line of input is an integer T, which tells how many test cases followed. 
The first line of each case is an integer N (3 <= N <= 500), which is the number of villages. Then come N lines, the i-th of which contains N integers, and the j-th of these N integers is the distance (the distance should be an integer within [1, 65536]) between village i and village j. There is an empty line after each test case.

Output

For each test case, you should output a line contains an integer, which is the length of the longest road to be built such that all the villages are connected, and this value is minimum.

Sample Input

1

3
0 990 692
990 0 179
692 179 0

Sample Output

692
注-此題為:    POJ  2485  Highways 

題意:     求最小生成樹的最大邊     Kruskal && Prim    模板

       注意輸出不要加空行  ,否則   PE 

已AC代碼:(Kruskal

#include<cstdio>
#define MAX 250000
#include<algorithm>
using namespace std;

int n,m,per[600]; // 並查集

struct node{
int u,v,w; //w為距離
}s[MAX];

bool cmp(node a,node b)
{
return a.w<b.w;
}

void into() //初始化
{
for(int i=0;i<=n;++i)
per[i]=i;
}

int find(int x) // 查找根節點
{
return x==per[x]?x:per[x]=find(per[x]);
}

bool join(int a,int b) //合並根節點,並判斷是否成環
{
int fa=find(a);
int fb=find(b);
if(fa!=fb)
{
per[fa]=fb;
return true;
}
return false;
}

int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int i,j,a,b,c,k,q;

scanf("%d",&n);
k=0;
for(i=1;i<=n;++i) //讀入數據
{
for(j=1;j<=n;++j)
{
scanf("%d",&a);
if(i>j) //只讀取一半 (i>j)的數據
{
s[k].u=i;
s[k].v=j;
s[k].w=a;
k++;
}
}
}

into(); //初始化根節點

sort(s,s+k,cmp); //按距離從小到大排序

int max=0;
for(i=0;i<k;++i)
{
if(join(s[i].u,s[i].v))
{
if(max<s[i].w) //最小生成樹的最大邊
max=s[i].w;
}
}

printf("%d\n",max);
}
return 0;
}


已AC代碼:( Prim

#include<cstdio>
#include<cstring>
#define INF 0xfffffff

int map[600][600],low[600];
int vis[600]; //map二維數組存圖,low記錄每2個點間最小權值,vis標記某點是否已訪問
int n,MAX;

void prim()
{
int min;
int i,j,pos;
memset(vis,0,sizeof(vis));
vis[1]=1;low[1]=0;
for(i=2;i<=n;++i) //從某點開始,分別標記vis和記錄該點pos
low[i]=map[1][i]; //第一次給low數組賦值 map的第一行

for(i=1;i<n;++i) //再運行n-1次,一次找一個最小
{
min=INF;
for(j=1;j<=n;++j) // 找出最小值min,記錄位置pos
{
if(vis[j]==0&&low[j]<min)
{
min=low[j];
pos=j;
}
}

vis[pos]=1; //標記該點已訪問
if(min>MAX) //最小生成樹的最大邊
MAX=min;
for(j=1;j<=n;++j) //更新權值low 把 map的 pos 行中比對應的 low 小的賦給low
if(vis[j]==0&&low[j]>map[pos][j])
low[j]=map[pos][j];
}
return ;
}


int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int i,j,a,b,c,k,q;

scanf("%d",&n);
memset(map,0,sizeof(map));
for(i=1;i<=n;++i) //建圖
{
for(j=1;j<=n;++j)
{
scanf("%d",&map[i][j]);
}
}
MAX=0;
prim(); //最小生成樹的最大邊
printf("%d\n",MAX);
}
return 0;
}


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com