// poj 2421 prim
/*最小生成树,用Prim算法
有n个城镇,已知每两个城镇的距离,其中某些城镇之间的道路已经修好,
要求用最少的路径修完剩下的城镇之间的路
*/
#include<stdio.h>
#define InF 2000
int g[110][110],bz[110],low[110];
int min,ans=0,Q,n,a,b;
void prim()
{
int i,j,k;
bz[1]=1,j=1;
for (i=2;i<=n;i++)
{
low[i]=g[1][i];
bz[i]=0;
}
for (i=1;i<n;i++)
{
min=InF;
for (k=2;k<=n;k++)
if ((low[k]<min)&&(bz[k]==0))
{
min=low[k];
j=k;
}
if (min<InF) ans+=min;
bz[j]=1;
for (k=2;k<=n;k++)
if ( (g[j][k]<low[k])&&(bz[k]==0)) low[k]=g[j][k];
}
}
int main()
{
int i,j;
while (scanf("%d",&n)!=EOF)
{
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
g[i][j]=0;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
scanf("%d",&g[i][j]);
scanf("%d",&Q);
for (i=1;i<=Q;i++)
{
scanf("%d%d",&a,&b); // a 到 b 的距离是0
g[a][b]=0;
g[b][a]=0;
}
prim();
printf("%d
",ans);
}
}
poj 2421
/*最小生成树,用Prim算法
有n个城镇,已知每两个城镇的距离,其中某些城镇之间的道路已经修好,
要求用最少的路径修完剩下的城镇之间的路
*/
#include<stdio.h>
#define INF 2000
int g[110][110],bz[110],low[110];
int min,ans,Q,n,a,b;
void prim()
{
int i,j,k;
ans=0; bz[1]=1;
for (i=2;i<=n;i++)
{ low[i]=g[1][i]; bz[i]=0; }
for (i=1;i<n;i++)
{ min=INF;
for (k=2;k<=n;k++)
if ( (low[k]<min)&&(bz[k]==0) ) { min=low[k]; j=k; }
ans+=min;
bz[j]=1;
for (k=2;k<=n;k++)
if ( (g[j][k]<low[k])&&(bz[k]==0)) low[k]=g[j][k];
}
}
int main()
{
int i,j;
while (scanf("%d",&n)!=EOF)
{ for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
scanf("%d",&g[i][j]);
scanf("%d",&Q);
for (i=1;i<=Q;i++)
{ scanf("%d%d",&a,&b); g[a][b]=0; g[b][a]=0; }
prim();
printf("%d
",ans);
}
}
// poj 2421 prim 普里姆(Prim)算法
/*最小生成树,用Prim算法
有n个城镇,已知每两个城镇的距离,其中某些城镇之间的道路已经修好,
要求用最少的路径修完剩下的城镇之间的路
*/
#include<stdio.h>
#define InF 2000
int g[110][110],bz[110],low[110];
int min,ans=0,Q,n,a,b;
void prim()
{
int i,j,k;
bz[1]=1,j=1;
for (i=2;i<=n;i++)
{
low[i]=g[1][i];
bz[i]=0;
}
for (i=1;i<n;i++)
{
min=InF;
for (k=2;k<=n;k++)
if ((low[k]<min)&&(bz[k]==0))
{
min=low[k];
j=k;
}
if (min<InF) ans+=min;
bz[j]=1;
for (k=2;k<=n;k++)
if ( (g[j][k]<low[k])&&(bz[k]==0)) low[k]=g[j][k];
}
}
int main()
{
int i,j;
while (scanf("%d",&n)!=EOF)
{
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
g[i][j]=0;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
scanf("%d",&g[i][j]);
scanf("%d",&Q);
for (i=1;i<=Q;i++)
{
scanf("%d%d",&a,&b);
g[a][b]=0;
g[b][a]=0;
}
prim();
printf("%d
",ans);
}
}
************************************************************
// POJ 2421 kruskal克鲁斯卡尔算法
#include<stdio.h>
#include<algorithm>
using namespace std;
int g[1001][1001],p[1001];
struct edge
{
int x,y,d;
} e[1000*1000/2];
int n,t,Q,ans;
int find(int x)
{
return p[x]==x?x:p[x]=find(p[x]);
}
void merge(int a,int b)
{ int c=find(a),d=find(b);
if (c!=d ) p[c]=d;
}
int cmp(edge a,edge b)
{
return a.d<b.d?1:0;
}
void ini()
{
int i,j;
t=0;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf("%d",&g[i][j]);
if(j>i)
{
e[t].x=i;
e[t].y=j;
e[t].d=g[i][j];
t++;
}
}
p[i]=i;
}
scanf("%d",&Q);
int a,b,c,d;
for(i=0;i<Q;i++)
{
scanf("%d %d",&a,&b);
merge(a,b);
}
sort(e,e+t,cmp);
}
void kruskal()
{ int a,b,i;
ans=0;
for(i=0;i<t;i++)
{
a=find(e[i].x),b=find(e[i].y);
if(a!=b)
{ ans+=e[i].d;
p[a]=b;
}
}
}
int main()
{
ini();
kruskal();
printf("%d
",ans);
return 0;
}