新知学习
最大值
在比赛中一般用到的最大值为0x3f3f3f3f
链式前向星
一般是用于存边之间的关系的,设定Edge结构体表示边的结构
其中 v 代表连接的点(编号), w 代表边的权值, next 代表下一条临接边(边的下标), 而edge数组的下标就代表着边的起点
基本结构
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100000;
// 创建边结构
struct Edge{
int v, w, next;
// 下一个点,边权,当前边的上一个边
}edge[MAXN*MAXN];
int tot, head[MAXN];
// 建边
void AddEdge(int u, int v, int w) {
// 建边
edge[tot].v = v;
edge[tot].w = w;
// 连边
edge[tot].next = head[u];
head[u] = tot++;
}
int main() {
// 初始化head
memset(head, -1, sizeof(head));
// 建边
int t; cin >> t;
for (int i = 0; i < t; i++) {
int u, v, w;
cin >> u >> v >> w;
AddEdge(u, v, w);
}
// 遍历 u 连接的所有边
int u; cin >> u;
for (int i = head[u]; i != -1; i = edge[i].next) {
cout << edge[i].v << " " << edge[i].w << endl;
}
}
图的最小树生成
//图的最小树生成
typedef struct edge
{
int u;
int v;
int w;
}ED;
ED e[10]; //数组大小根据实际情况来定,一般比m的最大值大1
int n, m;
int f[7] = { 0 }, sum = 0;
//f数组大小根据实际来定,一般比n的最大值大1
void quicksort(int left, int right)
{
int i, j;
ED t;
if (left > right)
return;
i = left;
j = right;
while (i != j)
{
while (e[j].w >= e[left].w && i < j)
j--;
while (e[i].w <= e[left].w && i < j)
i++;
if (i < j)
{
t = e[i];
e[i] = e[j];
e[j] = t;
}
}
t = e[left];
e[left] = e[i];
e[i] = t;
quicksort(left, i - 1);
quicksort(i + 1, right);
return;
}
int getf(int v)
{
if (f[v] == v)
return v;
else
{
f[v] = getf(f[v]);
return f[v];
}
}
int merge(int u, int v)
{
int t1, t2;
t1 = getf(v);
t2 = getf(u);
if (t1 != t2)
{
f[t2] = t1;
return 1;
}
return 0;
}
int main()
{
int count = 0;
cin >> n >> m;
for (int i = 1; i <= m; i++)
scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
quicksort(1, m);
for (int i = 1; i <= n; i++)
{
f[i] = i;
}
for (int i = 1; i <= m; i++)
{
if (merge(e[i].u, e[i].v))
{
count++;
sum += e[i].w;
}
if (count == n - 1)
break;
}
printf("%d", sum);
return 0;
}
//6 9
//2 4 11
//3 5 13
//4 6 3
//5 6 4
//2 3 6
//4 5 7
//1 2 1
//3 4 9
//1 3 2
练习题
P3366 【模板】最小生成树
#include<bits/stdc++.h>
#define N 200005
using namespace std;
int n,m,f[N],ans,bs,pd;
struct Edge{
int u,v,w;
}e[N];
int find(int x)
{
if (x == f[x])
return x;
else
{
f[x] = find(f[x]);
return f[x];
}
}
bool cmp(Edge x,Edge y){
return x.w<y.w;
}
int main(){
cin>>n>>m;
for(register int i=1;i<=n;i++) f[i]=i;
for(register int i=0;i<m;i++) cin>>e[i].u>>e[i].v>>e[i].w;
sort(e,e+m,cmp);
for(register int i=0;i<m;i++){
int fv=find(e[i].v),fu=find(e[i].u);
if(fv==fu) continue;
f[fv]=fu;
ans+=e[i].w;
if(++bs==n-1){
pd=1;
break;
}
}
if(!pd) cout<<"orz";
else cout<<ans;
return 0;
}
P4779 【模板】单源最短路径(标准版)
#include<bits/stdc++.h>
using namespace std;
const int MAX_INF = 0x3f3f3f3f;
const int M = 1e+6;
int head[M], cnt;
long long ans[M];
bool vis[M];
int m, n, s;
struct edge
{
int to;
int next;
int wei;
}edge[M];
struct priority
{
int ans;
int id;
bool operator <(const priority& x)const
{
return x.ans < ans;
}
};
void add(int x, int y, int z)
{
edge[++cnt].to = y;
edge[cnt].wei = z;
edge[cnt].next = head[x];
head[x] = cnt;
}
priority_queue<priority>q;
int main()
{
cin >> m >> n >> s;
for (int i = 1; i <= n; i++)
{
ans[i] = MAX_INF;
}
ans[s] = 0;
for (int i = 1; i <= n; i++)
{
int a, b, c;
cin >> a >> b >> c;
add(a, b, c);
}
int u;
q.push((priority) { 0, s });
while (!q.empty())
{
priority t = q.top();
q.pop();
u = t.id;
if (!vis[u])
{
vis[u] = 1;
for (int i = head[u]; i; i = edge[i].next)
{
int v = edge[i].to;
if (ans[v] > ans[u] + edge[i].wei)
{
ans[v] = ans[u] + edge[i].wei;
if (!vis[v])
{
q.push((priority){ ans[v], v });
}
}
}
}
}
for (int i = 1; i <= m; i++)
{
cout << ans[i] << ' ';
}
}