Borg Maze
原题链接https://vjudge.net/contest/352170#problem/I
本题给出一个地图,以及各个点的位置,大概意思就是所有点全部链接的最短路径,使用bfs枚举每一个点到其他所有点的位置,记录,然后计算即可。
Prim:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
long long pre[300005];
char map1[305][305];
long long vis1[305][305];
long long dis1[305][305];
long long mv[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
long long sum[30005];
long long map[3005][3005];
bool vis[300005];
long long dis[300005];
struct node1
{
long long x;
long long y;
} stu1[300005];
long long zz;
long long cnt;
long long ans;
long long n, m, k;
void bfs(long long x, long long y)
{
memset(vis1, 0, sizeof(vis1));
queue<node1> q;
node1 s, e;
s.x = x;
s.y = y;
dis1[s.x][s.y] = 0;
vis1[s.x][s.y] = 1;
q.push(s);
while (!q.empty())
{
s = q.front();
q.pop();
long long i, j;
for (i = 0; i < 4; i++)
{
e.x = s.x + mv[i][0];
e.y = s.y + mv[i][1];
if (e.x < 0 || e.y < 0 || e.x > n - 1 || e.y > m - 1 || vis1[e.x][e.y] == 1 || map1[e.x][e.y] == '#')
{
continue;
}
vis1[e.x][e.y] = 1;
dis1[e.x][e.y] = dis1[s.x][s.y] + 1;
q.push(e);
}
}
}
void prim()
{
ans = 0;
long long i, j;
for (i = 0; i < k; i++)
{
vis[i] = false;
dis[i] = map[0][i];
}
vis[0] = true;
for (i = 0; i < k - 1; i++)
{
long long minn = INF;
long long p = 1;
for (j = 0; j < k; j++)
{
if (!vis[j] && dis[j] < minn)
{
minn = dis[j];
p = j;
}
}
ans += minn;
vis[p] = true;
for (j = 0; j < k; j++)
{
if (!vis[j] && map[p][j] < dis[j])
{
dis[j] = map[p][j];
}
}
}
return;
}
int main()
{
long long t, i, j;
cin >> t;
while (t--)
{
scanf("%lld %lld", &m, &n);
char s[110];
gets(s);
for (i = 0; i < n; i++)
{
gets(map1[i]);
}
k = 0;
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
if (map1[i][j] == 'A' || map1[i][j] == 'S')//找出每一个需链接的地点坐标。
{
stu1[k].x = i;
stu1[k].y = j;
k++;
}
}
}
long long z = 0;
for (i = 0; i < k; i++)
{
memset(dis, 0, sizeof(dis));
bfs(stu1[i].x, stu1[i].y);//枚举每一个地点,与其他地点的关系。
for (j = i + 1; j < k; j++)
{
map[i][j] = map[j][i] = dis1[stu1[j].x][stu1[j].y];
}
}
prim();
cout << ans << endl;
}
return 0;
}
Kruskal:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <queue>
using namespace std;
long long pre[300005];
char map[305][305];
long long vis[305][305];
long long dis[305][305];
long long mv[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
long long sum[30005];
struct node
{
long long u;
long long v;
long long w;
} stu[3000005];
struct node1
{
long long x;
long long y;
} stu1[300005];
long long zz;
long long cnt;
long long ans;
long long n, m;
bool cmp(node x, node y)
{
return x.w < y.w;
}
long long find(long long x)
{
if (x == pre[x])
{
return x;
}
return pre[x] = find(pre[x]);
}
void join(long long x, long long y, long long w)
{
long long ss1 = find(x);
long long ss2 = find(y);
if (ss2 != ss1)
{
pre[ss2] = ss1;
// cnt--;
ans += w;
}
}
void bfs(long long x)
{
memset(vis, 0, sizeof(vis));
queue<node1>q;
node1 s, e;
s.x = stu1[x].x;
s.y = stu1[x].y;
dis[s.x][s.y] = 0;
vis[s.x][s.y] = 1;
q.push(s);
while(!q.empty())
{
s = q.front();
q.pop();
long long i, j;
for (i = 0; i < 4;i++)
{
e.x = s.x + mv[i][0];
e.y = s.y + mv[i][1];
if(e.x<0||e.y<0||e.x>n-1||e.y>m-1||vis[e.x][e.y]==1||map[e.x][e.y]=='#')
{
continue;
}
vis[e.x][e.y] = 1;
dis[e.x][e.y] = dis[s.x][s.y] + 1;
q.push(e);
}
}
}
int main()
{
long long t,i,j;
cin >> t;
while(t--)
{
scanf("%lld %lld", &m, &n);
char s[110];
gets(s);
for (i = 0; i < n;i++)
{
gets(map[i]);
}
long long k = 0;
for (i = 0; i < n;i++)
{
for (j = 0; j < m;j++)
{
if(map[i][j]=='A'||map[i][j]=='S')//找出需要计算的地点坐标
{
stu1[k].x = i;
stu1[k].y = j;
k++;
}
}
}
for (i = 0; i <= k;i++)
{
pre[i] = i;
}
long long z=0;
for (i = 0; i < k;i++)
{
memset(dis, 0, sizeof(dis));
bfs(i);
for (j = i + 1; j < k;j++)//枚举需要连接的所有道路的情况,
{
stu[z].u = i;
stu[z].v = j;
stu[z].w = dis[stu1[j].x][stu1[j].y];
z++;
}
}
sort(stu, stu + z, cmp);
ans = 0;
for (i = 0; i < z;i++)
{
join(stu[i].u, stu[i].v, stu[i].w);
}
cout << ans << endl;
}
return 0;
}