A. 最小生成树一·Prim算法 HihoCoder 1097
https://hihocoder.com/problemset/problem/1097
Prim算法模版题
#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
//#include <set>
//#include <queue>
//#include <iomanip>
//#include <map>
//#include <time.h>
using namespace std;
typedef long long ll;
inline int read() {
int x = 0;int f = 1; char c = getchar();
while(c<'0' || c>'9') {if(c=='-') f = -f; c = getchar();}
while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return x*f;
}
inline void write(int x) {
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[36];int tot = 0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
//mt19937 rnd(time(NULL));
const int inf = 0x3f3f3f3f;
const int maxn = 1e3+5;
int num[maxn][maxn];
int dis[maxn];
bool vis[maxn];
int n;
void init(int n ) {
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(i == j) num[i][j] = 0;
else num[i][j] = inf;
}
}
}
int prim(int a[][maxn]) {
int ans = 0;
memset(vis, false, sizeof(vis));
vis[0] = true;
for(int i = 1; i < n; i++)
dis[i] = num[0][i];
for(int i = 1; i < n; i++) {
int minn = inf,u = -1;
for(int j = 0; j < n; j++) {
if(!vis[j] && dis[j] < minn) {
minn = dis[j];
u = j;
}
}
if(ans == inf) return -1;
ans += minn;
vis[u] = 1;
for(int k = 0; k < n; k++) {
if(!vis[k]) dis[k] = min(dis[k],num[u][k]);
}
}
return ans;
}
int a[maxn];
int main() {
scanf("%d",&n);
init(n);
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
scanf("%d",&num[i][j]);
}
}
printf("%d\n",prim(num));
return 0;
}
B. 最小生成树二·Kruscal算法 https://hihocoder.com/problemset/problem/1098
Kruskal模版题
//这波要用到路径压缩,一定要
#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
//#include <set>
//#include <queue>
//#include <iomanip>
//#include <map>
//#include <time.h>
using namespace std;
typedef long long ll;
inline int read() {
int x = 0;int f = 1; char c = getchar();
while(c<'0' || c>'9') {if(c=='-') f = -f; c = getchar();}
while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return x*f;
}
inline void write(int x) {
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[36];int tot = 0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
//mt19937 rnd(time(NULL));
const int inf = 0x3f3f3f3f;
const int maxn = 1e6+10;
int father[maxn/10 + 5];
int sum;
int N,M;
struct node{
int u, v, w;
}edge[maxn];
void init(int n) {
for(int i = 0; i < n; i++) {
father[i] = i;
}
}
int find(int x) {
while(x!=father[x]) x=father[x] = father[father[x]];
return x;
}
bool cmp(node a, node b) {
return a.w < b.w;
}
int cnt;
void kruskal() {
sort(edge,edge+M,cmp);
for(int i = 0; i < M; i++) {
int eu = find(edge[i].u),ev = find(edge[i].v);
if(eu == ev) continue;
sum += edge[i].w;
father[ev] = eu;
if(++cnt == N - 1) {break;}
}
}
int main() {
scanf("%d%d",&N,&M);
for(int i = 0; i < M; i++){
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
}
init(N);
kruskal();
printf("%d\n",sum);
return 0;
}
C.最短路(Dijkstra)
https://hihocoder.com/problemset/problem/1081
#include <iostream>
#include <cstring>
using namespace std;
const int N = 10001;
const int M = 100001;
struct edge {
int v, w, next;
edge(){}
edge(int _v, int _w, int _next) {
v = _v;
w = _w;
next = _next;
}
} e[M * 2];
int head[N], size;
void init() {
memset(head, -1, sizeof(head));
size = 0; //边数
}
void insert(int u, int v, int w) {
e[size] = edge(v, w, head[u]);
head[u] = size++;
}
void insert2(int u, int v, int w) {
insert(u, v, w);
insert(v, u, w);
}
int n, m;
int dis[N];
bool vis[N];
void dijkstra(int u) {
memset(vis,false,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
dis[u] = 0;
for(int i = 0;i < n;++i) {
int mind = 1000000000,minj = -1;
for(int j = 1;j <= n; ++j){
if(!vis[j] && dis[j] < mind) {
minj = j;
mind = dis[j];
}
}
if(minj == -1) {
return;
}
vis[minj] = true;
for(int j = head[minj]; ~j; j = e[j].next) {
int v = e[j].v;
int w = e[j].w;
if(!vis[v] && dis[v] > dis[minj] + w) {
dis[v] = dis[minj] + w;
}
}
}
}
int main() {
init();
int u, v, w;
int ini,des;
cin >> n >> m >> ini >> des;
while(m--) {
cin >> u >> v >> w;
insert2(u, v, w);
}
dijkstra(ini);
cout << dis[des] << endl;
return 0;
}
D.最短路(Floyd)
https://hihocoder.com/problemset/problem/1089
#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <stack>
//#include <queue>
//#include <iomanip>
//#include <map>
//#include <time.h>
using namespace std;
typedef long long ll;
inline int read() {
int x = 0;int f = 1; char c = getchar();
while(c<'0' || c>'9') {if(c=='-') f = -f; c = getchar();}
while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return x*f;
}
inline void write(int x) {
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[36];int tot = 0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
//mt19937 rnd(time(NULL));
const int inf = 0x3f3f3f3f;
const int maxn = 1e2+10;
int a[maxn][maxn];
int n, m;
int u,v,w;
int main() {
cin >> n >> m;
for(int i = 1; i <=n; i++) {
for(int j = 1; j <= n; j++) {
if(i == j) {a[i][j] = 0;}
else {a[i][j] = inf;}
}
}
for(int i = 1; i <= m; i++) {
cin >> u >> v >> w;
a[u][v] =a[v][u] = min(a[u][v],w);
}
for(int k = 1; k <= n; k++) {
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
a[i][j] = min(a[i][j],a[i][k] + a[k][j]);
}
}
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n;j ++) {
cout << a[i][j] <<" ";
}cout << endl;
}
return 0;
}