用来练习链式前向星用的
/*************************************************************************
> File Name: main.cpp
> Author:Eagles
> Mail:None
> Created Time: 2018年09月05日 星期三 21时32分49秒
> Description:HDU1102,链式前向星
************************************************************************/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int n,m,cnt;
#define N 200
struct node
{
int to;
int nex;
int val;
}E[200*199];
int head[N];
int dis[N];
bool vis[N];
void addEdge(int a, int b, int val)
{
E[cnt].val=val;
E[cnt].to=b;
E[cnt].nex=head[a];
head[a]=cnt++;
E[cnt].val=val;
E[cnt].to=a;
E[cnt].nex=head[b];
head[b]=cnt++;
}
void changeEdge(int a, int b)//已经有路,则距离为0
{
int k=head[a];
while (k != -1)
{
if (b == E[k].to)
{
E[k].val=0;
break;
}
k=E[k].nex;
}
k=head[b];
while (k != -1)
{
if (E[k].to == a)
{
E[k].val=0;
break;
}
k=E[k].nex;
}
}
void init()
{
memset(head,-1,sizeof(head));
memset(vis,false,sizeof(vis));
memset(dis,0x3f3f3f3f,sizeof(dis));
cnt=0;
for (int i=0; i<n; i++)
{
for (int j=0; j<n; j++)
{
int val;
scanf("%d",&val);
if (j>i)
addEdge(i,j,val);
}
}
scanf("%d",&m);
while (m--)
{
int a,b;
scanf("%d%d",&a,&b);
changeEdge(a-1,b-1);
}
int k=head[0];
while (k != -1)
{
dis[E[k].to]=E[k].val;
k=E[k].nex;
}
vis[0]=true;
}
void prim()
{
int sum=0;
for (int i=0; i<n-1; i++)
{
int minn=1254215;
int tmp;
for (int j=0; j<n; j++)
{
if (!vis[j]&&dis[j]<minn)
{
minn=dis[j];
tmp=j;
}
}
vis[tmp]=true;
sum+=minn;
int k=head[tmp];
while (k != -1)
{
if (!vis[E[k].to]&&dis[E[k].to]>E[k].val)
dis[E[k].to]=E[k].val;
k=E[k].nex;
}
}
printf("%d\n",sum);
}
int main()
{
while (~scanf("%d",&n))
{
init();
prim();
}
return 0;
}