6 Tree & Graph

Tree


1.树的搜索

order traverse

思路1:bfs(要建树的数据结构)
思路2:dfs(要Node结构体)
struct sq {
	int index;
	int data;
};
void order(int i,int j) {
	if (node[i].lchild == -1 && node[i].rchild == -1) {
		in.push_back(i);
		return;
	}
	if (node[i].lchild != -1) {
		level.push_back({2 * j,node[i].lchild});
		order(node[i].lchild,2 * j);
	}
	in.push_back(i);
	if (node[i].rchild != -1) {
		level.push_back({2 * j+1,node[i].rchild});
		order(node[i].rchild,2 * j+1);
	}

}
bool cmp(sq a,sq b) {
	return a.index<b.index;
}

搜符合要求路径(不需要Node结构体)

const int maxn = 1010;
vector<int> g[maxn];//已知结点关系
void dfs(int x, int dp) {//depth运用
    path[depth] = w[x];
    if (g[x].size() == 0) {
        ll temp = 0;
        for (int i = 0; i <= depth; i++) temp += path[i];
        if (temp == s) {
            for (int i = 0; i <= depth; i++) ans[len].push_back(path[i]);
            len++;
        }
        return;
    }
    for (int i = 0; i < g[x].size(); i++) {
        dfs(g[x][i], dp + 1);
    }
}

2.空间问题

方法1:vector.resize(k)+vector本身也可以用下标(√)
方法2:int child[100]+int k=0;

3.查找vector中某值的lower uper

PAT1043

试比较以下和for循环+i–,会有for第一值退出时多减了
若是递增序列,不如直接找比他小的下一个,比他大的上一个

if(!isMirror) {
	while(i <= tail && pre[root] > pre[i]) i++;
	while(j > root && pre[root] <= pre[j]) j--;
} else {
	while(i <= tail && pre[root] <= pre[i]) i++;
	while(j > root && pre[root] > pre[j]) j--;
}

4.Node形参问题->段错误探讨

struct Node {
	vector<int> child;
	double sp = 0;
};
void dfs(int x,int dp) {
	int i;
	if(v[x].child.size()!=0) {
		for (i = 0; i<v[x].child.size(); ++i) 
		if (dp+1 > pw.size()-1)
			pw.push_back(pow(r, dp+1));
			dfs(v[x].child[i],dp+1);
	} 
	else sum += 1.0*v[x].sp*p*pw[dp];
}

如果将dfs第一个参数写为Node x会爆空间,更不谈存几个double了,直接用节点图或者层分布图vector g[maxn];

void dfs(int x, int depth) {
    if (g[x].size() == 0) {
        ans += (dat[x] * pow(1 + r, depth));
        return;
    }
    for (int i = 0; i < g[x].size(); i++) {
        dfs(g[x][i], depth + 1);
    }
}

段错误总结:

(1)越界访问

数组开小了导致指针指向了为开辟的数组区域,出现了越界访问多层for循环中内层循环本来打算写j或者k,却因为习惯或忘记误写成了外层循环的变量i或j,导致数组访问i或j下标的时候发⽣了越界

(2)栈空间和堆空间

⼤数组在main函数⾥⾯的话是存储在栈⾥,⽽栈空间是在进程创建时初始化,有固定的⼤⼩,⼀般为⼏⼗KB,所以太⼤的数组会耗光栈空间。⽽全局变量占⽤的堆空间,堆空间中的内存是按需分配,⾃由增⻓的,可以⾮常⼤,⽐如32位的系统中可以⼤到4GB。将⼤数组放在全局变量中能避免栈溢出

(3)树 null->data,null->left,null->right

5.并查集

int findf(int v){
    if(v!=father[v])
        f[v]=findf(f[v]);//注意点
    return f[v];
}
void uni(int a,int b){
    int fa = findf(a);
    int fb = findf(b);
    if(fa!=fb)
        f[fa] = fb;
}

Graph


1.数连通分量(并查集)

PAT1013 Battle Over Cities

当删除其中一个顶点及其相关的边之后,计算出剩下的图的连通分量,那么增加的边就应该是求出的连通分量-1

法1:每次dfs前判断visit[i]==0;

void dfs(int s) {
    visit[s] = 1;
    for(int i = 1; i<=n; ++i)
	if(g[s][i]==1&&visit[i]==0)dfs(i);
}
...main:
for (i = 0; i < k; ++i) {
    sum = 0;cin >> m;
    fill(visit.begin(),visit.end(),0);
    visit[m] = 1;
    for (j = 1; j<=n; ++j)
        if (visit[j] == 0){dfs(j);sum++;}
    printf("%d\n", sum-1);
}

法2:数根结点father[v]==v;

while(K--){
    int v;int num=0;
    scanf("%d",&v);
    iota(father,father+N+1,0);//初始化并查集
    for(int i=1;i<N+1;++i)
        if(i!=v)for(int j:graph[i])
            if(j!=v)uni(i,j);
    for(int i=1;i<=N;++i)
        if(i!=v&&father[i]==i)
            ++num;
    printf("%d\n",num-1);
}

Leetcode947

在二维平面上将石头放置在一些整数坐标点上。每个坐标点上最多只能有一块石头。现在,一个move将会移除与网格上的另一块石头共享一列或一行的一个石头。
int removeStones(vector<vector<int>>& stones) {
    if(stones.size() <= 1) return 0;
    int res = stones.size(), len = stones.size();
    vector<int> p(len,-1);
    for(int i =0;i < len;i++){
        for(int j = i+1;j < len;j++){
            if(stones[j][0] == stones[i][0] || stones[j][1] == stones[i][1])
                u(p, i, j);
        }
    }
    for(auto e : p){
        if(e == -1) res--;
    }
    return res;
}

2.有关是对边dfs还是点dfs

PAT1034

给出多个人之间的通话长度,按照这些通话将他们分成若干个组,各个组的总权值是该组内所有通话长度之和,每个人的权值是其参与的所有通话长度之和。求组数和组内通话最长的

每个点至少有一个连线,故可以对边搜数量关系的运用:边权和=点权和/2

之后的操作–PAT2019春7-3 Telefraud Detection

电信诈骗判断嫌疑犯,若犯人之间通过话说明是一个团伙
for(i=1;i<=n;++i)
    if(sus[i]==1)
        for(j=i+1;j<=n;++j)
            if(sus[j]==1&&g[i][j]>0&&g[j][i]>0)uni(i,j);
w=1;
for(i=1;i<=n;++i){
    if(sus[i]==1){
        if(mp[findf(i)]==0){
            mp[findf(i)]=w;
            gang[w].push_back(i);
            w++;
        }//将联通分量转换为gang
        else gang[mp[findf(i)]].push_back(i);
    }
}

PAT1021

给定N个结点和N-1条边,问能否构成一棵树,如果能,则输出作为树的根节点时使得整棵树深度最大的结点,如果不能,输出这个图中有几个连通分量。

能否构成树,要么有>1个连通分量,要么有环

3.Hamiltonian Cycle

(1)是否是N+1个点。 (2)除起点外,每个点是否只出现了1次 (3)经过的边是否存在 (4)起点是否等于终点

注意剔除重复点时要用set(往往隐含)

void check(int index) {
    int sum = 0, cnt, flag = 1;
    scanf("%d", &cnt);
    set<int> s;
    vector<int> v(cnt);
    for (int i = 0; i < cnt; i++) {
        scanf("%d", &v[i]);
        s.insert(v[i]);
    }
    for (int i = 0; i < cnt - 1; i++) {
        if(e[v[i]][v[i+1]] == 0) flag = 0;//3
        sum += e[v[i]][v[i+1]];
    }
    if (flag == 0)
    printf("Path %d: NA (Not a TS cycle)\n", index);
    else if(v[0]!=v[cnt-1]||s.size()!=n)//4,2
    printf("Path %d: %d (Not a TS cycle)\n", index, sum);
    else if(cnt != n + 1)printf("Path %d: %d (TS cycle)\n", index, sum);//1
    else printf("Path %d: %d (TS simple cycle)\n", index, sum);
}

4.dfs结构总结

void dfs(int x){
    temp.push_back(x);
    if (pre[x][0] == -1){
        ......
    }
    for(int i=0;i<pre[x].size();i++){
        dfs(pre[x][i]);
    }
    temp.pop_back();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园的建设目标是通过数据整合、全面共享,实现校园内教学、科研、管理、服务流程的数字化、信息化、智能化和多媒体化,以提高资源利用率和管理效率,确保校园安全。 智慧校园的建设思路包括构建统一支撑平台、建立完善管理体系、大数据辅助决策和建设校园智慧环境。通过云架构的数据中心与智慧的学习、办公环境,实现日常教学活动、资源建设情况、学业水平情况的全面统计和分析,为决策提供辅助。此外,智慧校园还涵盖了多媒体教学、智慧录播、电子图书馆、VR教室等多种教学模式,以及校园网络、智慧班牌、校园广播等教务管理功能,旨在提升教学品质和管理水平。 智慧校园的详细方案设计进一步细化了教学、教务、安防和运维等多个方面的应用。例如,在智慧教学领域,通过多媒体教学、智慧录播、电子图书馆等技术,实现教学资源的共享和教学模式的创新。在智慧教务方面,校园网络、考场监控、智慧班牌等系统为校园管理提供了便捷和高效。智慧安防系统包括视频监控、一键报警、阳光厨房等,确保校园安全。智慧运维则通过综合管理平台、设备管理、能效管理和资产管理,实现校园设施的智能化管理。 智慧校园的优势和价值体现在个性化互动的智慧教学、协同高效的校园管理、无处不在的校园学习、全面感知的校园环境和轻松便捷的校园生活等方面。通过智慧校园的建设,可以促进教育资源的均衡化,提高教育质量和管理效率,同时保障校园安全和提升师生的学习体验。 总之,智慧校园解决方案通过整合现代信息技术,如云计算、大数据、物联网和人工智能,为教育行业带来了革命性的变革。它不仅提高了教育的质量和效率,还为师生创造了一个更加安全、便捷和富有智慧的学习与生活环境。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值