1.1001
2.
3 0 990 692 990 0 179 692 179 0 1 1 2
179
3.有 N 的村庄,从 1 到 N 编号,和你应该有些修路,这样每两个村庄可以连接到彼此。我们说两个村庄 A 和 B 连接,当且仅当有一条路之间 A 和 B,或存在一个村庄 C 等,还有一条路之间连接 A 和 C,和 C 和 B。我们知道一些村庄之间已经有一些道路和你的工作是的生成一些道路这样的所有村庄都是连接和建的所有道路长度最小。输入第一行是一个整数 N (3 < = N < = 100),这是村庄的数字。然后来 N 行,其中第 i 个包含 N 的整数,而且这些 N 整数 j th 距离 (该距离应内的整数 [1,1000年]) 之间村庄 i 和村庄 j。然后还有一个整数 Q (0 < = Q < = N * (N + 1) / 2)。然后来的 Q 行,每行包含两个整数和 b (1 < = < b < = N),这意味着村庄之间的公路和村庄 b 建成。输出你应该输出行包含一个整数,是打造的所有村庄都被连接的所有道路的长度,此值是最低。
4.图算法
5.
#include <iostream>
#include <queue>
#include<stdio.h>
using namespace std;
const long MAXN=10000;
long father[MAXN];
long m,n;//点数 边数
//m标号从1开始
typedef struct
{
long from;
long to;
long cost;
}Edge;
bool operator <(const Edge &a, const Edge &b)
{
return a.cost>b.cost;
}
priority_queue<Edge> q;
Edge e[100005];
void MakeSet()
{
long i;
for (i=0;i<=m;++i)
{
father[i]=i;
}
}
long Find(long i)
{
long r=i;
while (father[r]!=r)
{
r=father[r];
}
while (father[i]!=r)
{
long j=father[i];
father[i]=r;
i=j;
}
return r;
}
void Unition(long x,long y)
{
long fx=Find(x);
long fy=Find(y);
if (fx!=fy)
{
father[fx]=fy;
}
}
void Init()
{
while (!q.empty())
{
q.pop();
}
MakeSet();
long i,j;
long cc;
int pp=0;
for(i=1;i<=m;++i)
{
for(j=1;j<=m;j++)
{
scanf("%ld",&cc);
e[pp].from=i;
e[pp].to=j;
e[pp].cost=cc;
pp++;
}
}
long qqq,aaa,bbb;
scanf("%ld",&qqq);
for(i=0;i<qqq;i++)
{
scanf("%ld%ld",&aaa,&bbb);
for(j=0;j<pp;j++)
{
if(e[j].from==aaa)
{
if(e[j].to==bbb)
{
e[j].cost=0;
}
}
if(e[j].from==bbb)
{
if(e[j].to==aaa)
{
e[j].cost=0;
}
}
}
}
for(i=0;i<pp;i++)
{
q.push(e[i]);
}
}
void print(long cost)
{
printf("%ld\n",cost);
}
void Kruskal()
{
Init();
long t=0;//表示合并次数
long cost=0;
Edge e;
while (!q.empty()&&t<m-1)
{
e=q.top();
long v1=e.from;
long v2=e.to;
if (Find(v1)!=Find(v2))
{
Unition(v1,v2);
cost+=e.cost;
++t;
}
q.pop();
}
print(cost);
}
int main()
{
while(~scanf("%ld",&m))//输入点与边
{
Kruskal();
}
return 0;
}