24-2-20学习总结

新知学习

最大值

在比赛中一般用到的最大值为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] << ' ';
    }

}

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值