### 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

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

#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;
}

#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;
}