虚树练习集锦

什么是虚树?

比方说有一棵很大很大的树

但是每次会指定一些节点,这些点的个数很少,我们需要在树上进行DP

n的范围会达到百万级别

然而点的个数不会超过1000个

显然很多点都是没有用的点


我们需要把信息浓缩一下,构造出一棵新的树出来


恩。那么哪些会是虚树上的关键节点呢?


除了给定的点外还有一些点的LCA


不会构造怎么办?!


不用担心!构造虚树也是有个模板的



[例题1][Bzoj 2286][Sdoi2011]消耗战


在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达。现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军胜利在望。已知在其他k个岛屿上有丰富能源,为了防止敌军获取能源,我军的任务是炸毁一些桥梁,使得敌军不能到达任何能源丰富的岛屿。由于不同桥梁的材质和结构不同,所以炸毁不同的桥梁有不同的代价,我军希望在满足目标的同时使得总代价最小。
侦查部门还发现,敌军有一台神秘机器。即使我军切断所有能源之后,他们也可以用那台机器。机器产生的效果不仅仅会修复所有我军炸毁的桥梁,而且会重新随机资源分布(但可以保证的是,资源不会分布到1号岛屿上)。不过侦查部门还发现了这台机器只能够使用m次,所以我们只需要把每次任务完成即可。
Input
第一行一个整数n,代表岛屿数量。
接下来n-1行,每行三个整数u,v,w,代表u号岛屿和v号岛屿由一条代价为c的桥梁直接相连,保证1<=u,v<=n且1<=c<=100000。
第n+1行,一个整数m,代表敌方机器能使用的次数。
接下来m行,每行一个整数ki,代表第i次后,有ki个岛屿资源丰富,接下来k个整数h1,h2,…hk,表示资源丰富岛屿的编号。
Output
输出有m行,分别代表每次任务的最小代价。
 


Sample Input
10
1 5 13
1 9 6
2 1 19
2 4 8
2 3 91
5 6 8
7 5 4
7 8 31
10 7 9
3
2 10 6
4 5 7 8 3
3 9 4 6


Sample Output
12
32
22
【数据规模和约定】
对于100%的数据,2<=n<=250000,m>=1,sigma(ki)<=500000,1<=ki<=n-1


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 500010
 
using namespace std;
 
typedef long long ll;
 
const ll inf = 1LL<<60;
 
int n;
 
struct Edge{
    int to, next, dis;
}edge[maxn];
 
int h[maxn], cnt;
 
void add(int u, int v){
    cnt ++;
    edge[cnt].to = v;
    edge[cnt].next = h[u];
    h[u] = cnt;
}
 
 
struct EG{
    int to, next, dis;
}G[maxn];
 
int hG[maxn], cntG;
 
void addG(int u, int v, int w){
    cntG ++;
    G[cntG].to = v;
    G[cntG].next = hG[u];
    G[cntG].dis = w;
    hG[u] = cntG;
}
 
int root, t[maxn], fa[maxn], dep[maxn], dfn[maxn], dfs_clock;
 
bool cmp(int x, int y){
    return dfn[x] < dfn[y];
}
 
int anc[maxn][20];
 
ll dis[maxn];
 
void dfs(int u){
    dep[u] = dep[fa[u]] + 1;
    dfn[u] = ++ dfs_clock;
    for(int i = hG[u];i;i = G[i].next){
        int v = G[i].to;
        if(v == fa[u])continue;
        dis[v] = min(dis[u], (ll)G[i].dis);
        fa[v] = u;
        dfs(v);
    }
}
 
 
void pre_LCA(){
    for(int i=1;i<=n;i++)
        anc[i][0] = fa[i];
    for(int j=1;1<<j<=n;j++)
        for(int i=1;i<=n;i++){
            int a = anc[i][j-1];
            if(~a)anc[i][j] = anc[a][j-1];
        }
}
 
int ask_LCA(int p, int q){
    if(dep[p] < dep[q])
        swap(p, q);
 
    int log;
    for(log=1;1<<log<=dep[p];log++);log--;
    for(int i=log;i>=0;i--)
        if(~anc[p][i] && dep[anc[p][i]] >= dep[q])
            p = anc[p][i];
    if(p == q)return p;
    for(int i=log;i>=0;i--)
        if(~anc[p][i] && anc[p][i] != anc[q][i])
            p = anc[p][i], q = anc[q][i];
    return fa[p];
}
 
int st[maxn], top;
 
ll dp[maxn];
 
bool mark[maxn];
 
void Tree_DP(int u, bool istrue){
    dp[u] = dis[u];
     
    if(istrue){
        for(int i=h[u];i;i=edge[i].next)
            Tree_DP(edge[i].to, 1);
        mark[u] = false;
        h[u] = 0;
        return;
    }
     
    ll tmp = 0;
    for(int i=h[u];i;i=edge[i].next){
        int v = edge[i].to;
        Tree_DP(v, istrue | mark[v]);
        tmp += dp[v];
    }
    mark[u] = 0;
    if(!h[u] || mark[u])tmp = inf;
    dp[u] = min(dp[u], tmp);
    h[u] = 0;
}
 
int main(){
    scanf("%d", &n);
    int u, v, d;
    for(int i=1; i<n; i++){
        scanf("%d%d%d", &u, &v, &d);
        addG(u, v, d);
        addG(v, u, d);
    }
 
    root = 1;
     
    dis[root] = inf;
 
    dfs(root);
 
    memset(anc, -1, sizeof anc);
 
    pre_LCA();
 
    int test, K;
    scanf("%d", &test);
 
    while(test --){
        scanf("%d", &K);
         
        for(int i=1;i<=K;i++){
            scanf("%d", &t[i]);
            mark[t[i]] = true;
        }
 
        sort(t+1, t+1+K, cmp);
        st[top = 1] = root;
        cnt = 0;
        for(int i=1;i<=K;i++){
            int x = t[i],f = ask_LCA(st[top], x);
            while(dep[f] < dep[st[top]]){
                if(dep[f] >= dep[st[top-1]]){
                    add(f, st[top]);
                    top --;
                    if(f != st[top])st[++ top] = f;
                    break;
                }
                add(st[top-1], st[top]);
                top --;
            }
            if(st[top] != x)st[++ top] = x;
        }
         
        while(-- top)add(st[top], st[top+1]);
         
        Tree_DP(root, 0);
        printf("%lld\n", dp[root]);
    }
 
    return 0;
}



[例题2][Bzoj3611][Heoi2014]大工程

国家有一个大工程,要给一个非常大的交通网络里建一些新的通道。 

我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上。 
在 2 个国家 a,b 之间建一条新通道需要的代价为树上 a,b 的最短路径。
 现在国家有很多个计划,每个计划都是这样,我们选中了 k 个点,然后在它们两两之间 新建 C(k,2)条 新通道。
现在对于每个计划,我们想知道:
 1.这些新通道的代价和
 2.这些新通道中代价最小的是多少 
3.这些新通道中代价最大的是多少
Input
第一行 n 表示点数。
 接下来 n-1 行,每行两个数 a,b 表示 a 和 b 之间有一条边。
点从 1 开始标号。 接下来一行 q 表示计划数。
对每个计划有 2 行,第一行 k 表示这个计划选中了几个点。
 第二行用空格隔开的 k 个互不相同的数表示选了哪 k 个点。
Output


输出 q 行,每行三个数分别表示代价和,最小代价,最大代价。 


Sample Input
10 
2 1 
3 2 
4 1 
5 2 
6 4 
7 5
8 6 
9 7 
10 9 


5 4 

10 4 

5 2 

6 1 

6 1 


Sample Output
3 3 3 
6 6 6
1 1 1 
2 2 2 
2 2 2 
HINT
n<=1000000 
q<=50000并且保证所有k之和<=2*n 


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 1000010
using namespace std;
 
typedef long long ll;
 
int n;
 
struct Edge_{
    int to, next;
}G[maxn << 1];
int hG[maxn], cntG;
void addG(int u, int v){
    cntG ++;
    G[cntG].to = v;
    G[cntG].next = hG[u];
    hG[u] = cntG;
}
 
const int root = 1;
 
int fa[maxn], anc[maxn][21];
 
int dep[maxn], dfn[maxn], dfs_clock;
 
 
void dfs(int u){
    dep[u] = dep[fa[u]] + 1;
    dfn[u] = ++ dfs_clock;
    for(int i = hG[u];i; i = G[i].next){
        int v = G[i].to;
        if(v == fa[u])continue;
        fa[v] = u;
        dfs(v);
    }
}
 
bool cmp(const int& x, const int& y){
    return dfn[x] < dfn[y];
}
 
int t[maxn], st[maxn], top;
 
void pre_LCA(){
    for(int i = 1; i <= n; i ++)
        anc[i][0] = fa[i];
    for(int j = 1; 1 << j <= n; j ++)
        for(int i = 1; i <= n; i ++){
            int a = anc[i][j - 1];
            if(a)anc[i][j] = anc[a][j - 1];
        }
}
 
int ask_LCA(int p, int q){
    if(p == 0 || q == 0)return 0;
    if(dep[p] < dep[q])swap(p, q);
    int log;
    for(log = 1; 1 << log <= n; log ++);
    log --;
    for(int i = log; ~i; i --)
        if(anc[p][i] && dep[anc[p][i]] >= dep[q])
            p = anc[p][i];
    if(p == q)return p;
    for(int i = log; ~i; i --)
        if(anc[p][i] && anc[p][i] != anc[q][i])
            p = anc[p][i], q = anc[q][i];
    return fa[p];
}
 
struct Edge{
    int to, next;
    ll dis;
}edge[maxn];
 
int h[maxn], cnt;
 
void add(int u, int v){
    cnt ++;
    edge[cnt].to = v;
    edge[cnt].next = h[u];
    edge[cnt].dis = dep[v] - dep[u];
    h[u] = cnt;
}
 
long long ans1;
 
int ans2, ans3;
 
int size[maxn];
int mx[maxn], mn[maxn];
 
bool mark[maxn];
 
ll dp[maxn];
 
const int inf = 0x7fffffff / 2;
 
void Tree_DP(int u){
    size[u] = mx[u] = 0;
    mn[u] = inf;
    dp[u] = 0;
    ll now = 0;
    for(int i = h[u]; i; i = edge[i].next){
        Tree_DP(edge[i].to);
        size[u] += size[edge[i].to];
    }
     
    size[u] += mark[u];
     
    int max1 = 0, max2 = 0, min1 = inf, min2 = inf;
     
    for(int i = h[u]; i; i = edge[i].next){
        int v = edge[i].to;
        now += (dp[v] + size[v] * edge[i].dis) * (size[u] - size[v]);
        dp[u] += size[v] * edge[i].dis + dp[v];
        mn[u] = min(mn[u], mn[v] + (int)edge[i].dis);
        mx[u] = max(mx[u], mx[v] + (int)edge[i].dis);
        int tmp = mn[v] + edge[i].dis;
        if(!mark[u]){
            if(tmp <= min1){
                min2 = min1;
                min1 = tmp;
            }
            else min2 = min(min2, tmp);
        }
        tmp = mx[v] + edge[i].dis;
        if(tmp >= max1){
            max2 = max1;
            max1 = tmp;
        }
        else max2 = max(max2, tmp);
    }
 
    ans1 += now;
 
    if(mark[u]){
        ans2 = min(ans2, mn[u]);
        mn[u] = 0;
    }
    else ans2 = min(ans2, min1 + min2);
    ans3 = max(ans3, max1 + max2);
    h[u] = 0;
}
 
int main(){
#ifndef ONLINE_JUDGE
    freopen("tree.in", "r", stdin);
    freopen("tree.out", "w", stdout);
#endif
    scanf("%d", &n);
    int u, v;
     
    for(int i = 1; i < n; i++){
        scanf("%d%d", &u, &v);
        addG(u, v);
        addG(v, u);
    }
     
    dfs(root);
    pre_LCA();
     
    int test, K;
    scanf("%d", &test);
    while(test --){
        scanf("%d", &K);
        for(int i = 1; i <= K; i++)
            scanf("%d", &t[i]);
        sort(t + 1, t + 1 + K, cmp);
        int root = t[1];
        for(int i = 2; i <= K; i++)
            root = ask_LCA(t[i], root);
             
        top = cnt = 0;
        st[++ top] = root;
         
        for(int i = 1; i <= K; i ++){
            int x = t[i], f = ask_LCA(st[top], x);
            while(dep[f] < dep[st[top]]){
                if(dep[f] >= dep[st[top - 1]]){
                    add(f, st[top --]);
                    if(f != st[top])
                        st[++ top] = f;
                    break;
                }
                add(st[top - 1], st[top]);
                top --;
            }
            if(st[top] != x)
                st[++ top] = x;
        }
         
        while(-- top)
            add(st[top], st[top + 1]);
             
        ans1 = 0;
        ans2 = n + 1;
        ans3 = 0;
         
        for(int i = 1; i <= K; i ++)
            mark[t[i]] = true;
             
         
        Tree_DP(root);
        printf("%lld %d %d\n", ans1, ans2, ans3);
        for(int i = 1; i <= K; i ++)
            mark[t[i]] = false;
        size[0] = 0;
    }
 
    return 0;
}




[例题3][Codeforces 613D]


D. Kingdom and its Cities
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Meanwhile, the kingdom of K is getting ready for the marriage of the King's daughter. However, in order not to lose face in front of the relatives, the King should first finish reforms in his kingdom. As the King can not wait for his daughter's marriage, reforms must be finished as soon as possible.

The kingdom currently consists of n cities. Cities are connected by n - 1 bidirectional road, such that one can get from any city to any other city. As the King had to save a lot, there is only one path between any two cities.

What is the point of the reform? The key ministries of the state should be relocated to distinct cities (we call such cities important). However, due to the fact that there is a high risk of an attack by barbarians it must be done carefully. The King has made several plans, each of which is described by a set of important cities, and now wonders what is the best plan.

Barbarians can capture some of the cities that are not important (the important ones will have enough protection for sure), after that the captured city becomes impassable. In particular, an interesting feature of the plan is the minimum number of cities that the barbarians need to capture in order to make all the important cities isolated, that is, from all important cities it would be impossible to reach any other important city.

Help the King to calculate this characteristic for each of his plan.

Input

The first line of the input contains integer n (1 ≤ n ≤ 100 000) — the number of cities in the kingdom.

Each of the next n - 1 lines contains two distinct integers uivi (1 ≤ ui, vi ≤ n) — the indices of the cities connected by the i-th road. It is guaranteed that you can get from any city to any other one moving only along the existing roads.

The next line contains a single integer q (1 ≤ q ≤ 100 000) — the number of King's plans.

Each of the next q lines looks as follows: first goes number ki — the number of important cities in the King's plan, (1 ≤ ki ≤ n), then follow exactly ki space-separated pairwise distinct numbers from 1 to n — the numbers of important cities in this plan.

The sum of all ki's does't exceed 100 000.

Output

For each plan print a single integer — the minimum number of cities that the barbarians need to capture, or print  - 1 if all the barbarians' attempts to isolate important cities will not be effective.

Sample test(s)
input
4
1 3
2 3
4 3
4
2 1 2
3 2 3 4
3 1 2 4
4 1 2 3 4
output
1
-1
1
-1
input
7
1 2
2 3
3 4
1 5
5 6
5 7
1
4 2 4 6 7
output
2
Note

In the first sample, in the first and the third King's plan barbarians can capture the city 3, and that will be enough. In the second and the fourth plans all their attempts will not be effective.

In the second sample the cities to capture are 3 and 5.


题目大意:

给定一棵树(n <= 100000)

多组询问(q <= 100000)

给定一些关键节点

最少切断多少条边才能让关键节点两两不连通?


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 500010
using namespace std;
int n,k;
int now[maxn];
struct Edge{
	int to,next;
}edge[maxn<<1],G[maxn<<1];
int h[maxn],cnt,H[maxn],CNT;
void add(int u,int v){
	cnt++;
	edge[cnt].to=v;
	edge[cnt].next=h[u];
	h[u]=cnt;
}
int fa[maxn],dep[maxn],dfn[maxn],dfs_clock;
const int root=1;
bool cmp(int x,int y){return dfn[x]<dfn[y];}

void re_add(int u,int v){
	CNT++;
	G[CNT].to=v;
	G[CNT].next=H[u];
	H[u]=CNT;
}

void dfs(int u){
	dfn[u]=++dfs_clock;
	dep[u]=dep[fa[u]]+1;
	for(int i=h[u];i;i=edge[i].next){
		int v=edge[i].to;
		if(v==fa[u])continue;
		fa[v]=u;
		dfs(v);
	}
}
int anc[maxn][20];
void pre_LCA(){
	memset(anc,-1,sizeof anc);
	for(int i=1;i<=n;i++)
		anc[i][0]=fa[i];
	for(int j=1;1<<j<=n;j++)
		for(int i=1;i<=n;i++){
			int a=anc[i][j-1];
			if(~a)anc[i][j]=anc[a][j-1];
		}
}
int ask_LCA(int p,int q){
	if(dep[p]<dep[q])swap(p,q);
	int log;
	for(log=1;1<<log<=dep[p];log++);log--;
	for(int i=log;i>=0;i--)
		if(~anc[p][i]&&dep[anc[p][i]]>=dep[q])
			p=anc[p][i];
	if(p==q)return p;
	for(int i=log;i>=0;i--)
		if(~anc[p][i]&&anc[p][i]!=anc[q][i])
			p=anc[p][i],q=anc[q][i];
	return fa[p];
}
int sta[maxn],top;
int mark[maxn],ans;
int dp[maxn][2];
void Tree(int u){
	for(int i=H[u];i;i=G[i].next)
		Tree(G[i].to);
	if(mark[u]){
		dp[u][1]=0;
		if(!fa[u])dp[u][0]=0;
		else dp[u][0]=1;
		for(int i=H[u];i;i=G[i].next){
			int v=G[i].to;
			dp[u][1]+=dp[v][0];
			dp[u][0]+=dp[v][0];
		}
	}
	else{
		dp[u][1]=0;
		dp[u][0]=1;
		int tmp=0,d=0;
		for(int i=H[u];i;i=G[i].next){
			int v=G[i].to;
			tmp+=dp[v][0];
			dp[u][1]+=dp[v][0];
			dp[u][0]+=min(dp[v][0],dp[v][1]);
			d=min(d,dp[v][1]-dp[v][0]);
		}
		dp[u][1]+=d;
		dp[u][0]=min(dp[u][0],tmp);
	}
	H[u]=0;
}
int main(){
	scanf("%d",&n);
	int u,v;
	for(int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		add(u,v),add(v,u);
	}
	dfs(root);
	pre_LCA();
	int test;
	scanf("%d",&test);
	while(test--){
		scanf("%d",&k);
		for(int i=1;i<=k;i++)
			scanf("%d",&now[i]);
		for(int i=1;i<=k;i++)
			mark[now[i]]=true;
		int flag=true;
		for(int i=1;i<=k;i++)
			if(mark[fa[now[i]]]){
				flag=false;
				break;
			}
		if(flag){
			for(int i=1;i<=k;i++)
				now[i+k]=fa[now[i]];
			k<<=1;
			sort(now+1,now+1+k,cmp);
			k=unique(now+1,now+1+k)-now-1;
			//Build_tree
			sta[++top]=root;
			for(int i=1;i<=k;i++){
				int x=now[i],f=ask_LCA(x,sta[top]);
				while(dep[sta[top]]>dep[f]){
					if(dep[sta[top-1]]<=dep[f]){
						re_add(f,sta[top--]);
						if(sta[top]!=f)sta[++top]=f;
						break;
					}
					re_add(sta[top-1],sta[top]);top--;
				}
				if(x!=sta[top])sta[++top]=x;
			}
			while(--top)re_add(sta[top],sta[top+1]);
			ans=0;
			Tree(root);
			printf("%d\n",min(dp[root][1],dp[root][0]));
		}
		else printf("-1\n");
		CNT=0;
		for(int i=1;i<=k;i++)
			mark[now[i]]=false;
	}

	return 0;
}


虚树+DP

看来要好好学树形DP了。。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1章 计算机与C++编程简介 1.1 简介 1.2 什么是计算机 1.3 计算机组成 1.4 操作系统的变革 I.5 个人计算、分布式计算与客户/a匠务器计算 l. 6 机器语言、汇编语言和高级语言 1.7 C语言与C++的历史 1.8 C++标准库 1.9 Java、Internet与万维网 1.10 其他高级语言 1.11 结构化编程 1.12 典型C++环境基础 1.13 C++与本书的一般说明 1.14 C++编程简介 1.15 简单程序:打印一行文本 1.16 简单程序:两个整数相加 1.17 内存的概念 1.18 算术运算 1.19 判断:相等与关系运算符 1.20 新型头文件与名字空间 1.21 有关对象的思考 小结 术语 自测练习 自测练习答案 练习 第2章 控制结构 2.1 简介 2.2 算法 2.3 伪代码 2.4 控制结构 2.5 if选择结构 2.6 if/e1se选择结构 2.7 while重复结构 2.8 构造算法:实例研究1(计数器控制重复) 2.9 构造算法与自上而下逐步完善:实例研究2(标记控制重复) 2.10 构造算法与自上而下逐步完善:实例研究3(嵌套控制结构) 2.11 赋值运算符 2.12 自增和自减运算符 2.13 计数器控制循环的要点 2.14 for重复结构 2.15 for结构使用举例 2.16 switch多项选择结构 2.17 do/while重复结构 2.18 break和continue语句 2.19 逻辑运算符 2.20 混淆相等(.==)与赋值(=)运算符 2.21 结构化编程小结 2.22 有关对象的思考:确定问题中的对象 小结 术语 自测练习 自测练习答案 练习 第3章 函数 3.1 简介 3.2 C++程序组件 3.3 数学函数库 3.4 函数 3.5 函数定义 3.6 函数原型 3.7 头文件 3.8 随机数产生器 3.9 案例:机会游戏与enum简介 3.10 存储类 3.11 作用域规则 3.12 递归 3.13 使用递归举例:Fibonacci数列 3.14 递归与迭代 3.15 带空参数表的函数 3.16 内联函数 3.17 引用与引用参数 3.18 默认参数 3.19 一元作用域运算符 3.20 函数重载 3.21 函数模板 3.22 有关对象的思考:确定对象属性 小结 术语 自测练习 自测练习答案 练习 第4章 数组 4.1 简介 4.2 数组 4.3 声明数组 4.4 使用数组的举例 4.5 将数组传递给函数 4.6 排序数组 4.7 实例研究:用数组计算平均值、中数和模 4.8 查找数组:线性查找与折半查找 4.9 多下标数组 4.10 有关对象的思考:确定类的行为 小结 术语 自测练习 自测练习答案 练习 递归练习 第5章 指针与字符串 5.1 简介 5.2 指针变量的声明与初始化 5.3 指针运算符 5.4 按引用调用函数 5.5 指针与常量限定符 5.6 按引用调用的冒泡排序 5.7 指针表达式与指针算法 5.8 指针与数组的关系 5.9 指针数组 5.10 实例研究:洗牌与发牌 5.11 函数指针 5.12 字符与字符串处理简介 5.12.1 字符与字符串基础 5.12.2 字符串处理库的字符串操作函数 5.13 有关对象的思考:对象间的交互 小结 术语 自测练习 自测练习答案 练习 特殊小节:建立自己的计算机 更多的指针练习 字符串操作练习 特殊小节:高级字符串操作练习 复杂字符串操作练习 第6章 类与数据抽象(一) 6.1 简介 6.2 结构定义 6.3 访问结构成员 6.4 用struct实现用户自定义类型Time 6.5 用类实现Time抽象数据类型 6.6 类范围与访问类成员 6.7 接口与实现方法的分离 6.8 控制对成员的访问 6.9 访问函数与工具函数 6.10 初始化类对象:构造函数 6.11 在构造函数中使用默认参数 6.12 使用析构函数 6.13 何时调用构造函数与析构函数 6.14 使用数据成员和成员函数 6.15 微妙的陷阱:返回对Private数据成员的引用 6.16 通过默认的成员复制进行赋值 6.17 软件复用性 6.18 有关对象的思考:编写电梯模拟程序的类 小结 术语 自测练习 自测练习答案 练习 第7章 类与数据抽象(二) 7. 1 简介 7.2 const(常量)对象与const成员函数 7.3 复合:把对象作为类成员 7.4 友元函数与友元类 7.5 使用this指针 7.6 动态内存分配与new和delete运算符 7.7 static类成员 7.8 数据抽象与信息隐藏 7.8.1 范例:数组抽象数据类型 7.8.2 范例:字符串抽象数据类型 7.8.3 范例:队列抽象数据类型 7.9 容器类与迭代 7.10 代理类 7.11 有关对象的思考:在电梯模拟程序中使用复合和动态对象管理 小结 术语 自测练习 自测练习答案 练习 第8章 运算符重载 8.1 简介 8.2 运算符重载的基础 8.3 运算符重载的限制 8.4 用作类成员与友元函数的运算符函数 8.5 重载流插入与流读取运算符 8.6 重载一元运算符 8.7 重载二元运算符 8.8 实例研究:Array类 8.9 类型之间的转换 8.10 实例研究:String类 8.11 重载十十与—— 8.12 实例研究:Date类 小结 术语 自测练习 自测练习答案 练习 第9章 继承 9.1 简介 9.2 继承:基类和派生类 9.3 Protected成员 9.4 把基类指针强制转换为派生类指针 9.5 使用成员函数 9.6 在派生类中重定义基类成员 9.7 Public、Protected和Private继承 9.8 直接基类和间接基类 9.9 在派生类中使用构造函数和析构函数 9.10 将派生类对象隐式转换为基类对象 9.11 关于继承的软件工程 9.12 复合与继承的比较 9.13 对象的“使用”关系和“知道”关系 9.14 实例研究:类Point、CircIe和Cylinder 9.15 多重继承 小结 术语 自测练习 自测练习答案 练习 第10章 虚函数和多态性 10.1 简介 10.2 类型域和switch语句 10.3 虚函数 10.4 抽象基类和具体类 10.5 多态性 10.6 实例研究:利用多态性的工资单系统 10.7 新类和动态关联 10.8 虚析构函数 10.9 实例研究:继承接口和实现 10.10 多态、虚函数和动态关联 小结 术语 自测练习 自测练习答案 练习 第11章 C++输入/输出流 11.1 简介 11.2 流 11.2.1 iosbeam类库的头文件 11.2.2 输入/输出流类和对象 11.3 输出流 11.3.1 流插入运算符 11.3. 2 连续使用流插入/流读取运算符 11.3.3 输出char类型的变量 11.3.4 用成员函数put输出字符和put函数的连续调用 11.4 输入流 11.4.1 流读取运算符 11.4.2 成员函数get和getline 11.4.3 istream类中的其他成员函数(Peek、Putback和ignore) 11.4.4 类型安全的I/0 11.5 成员函数read、gcount和write的无格式输人/输出 11.6 流操纵算子 11.6.1 整数流的基数:流操纵算子dec、oct、hex和setbase 11.6.2 设置浮点数精度(Precision、setprecision) 11.6.3 设置域宽(setw、width) 11.6.4 用户自定义的流操纵算子 11.7 流格式状态 11.7.1 格式状态标志 11.7.2 尾数零和十进制小数点(ios:showpoint) 11.7.3 对齐(ios::left、ios::right、ios::internal) 11.7.4 设置填充字符(fill、setfill) 11.7.5 整数流的基数:(ios::dec、ios::oct、ios::hex、ios::showbase) 11. 7.6 浮点数和科学记数法(ios::scientific、ios::fixed) 11.7.7 大/小写控制(ios:uppercase) 11.7.8 设置及清除格式标志(flags、setiosflags、resetiosflags) 11.8 流错误状态 11.9 把输出流连到输入流上 小结 术语 自测练习 自测练习答案 练习 第12章 模板 12.1 简介 12.2 函数模板 12.3 重载模板函数 12.4 类模板 12.5 类模板与非类型参数 12.6 模板与继承 12.7 模板与友元 12.8 模板与static成员 小结 术语 自测练习 自测练习答案 练习 第13章 异常处理 13.1 简介 13.2 何时使用异常处理 13.3 其他错误处理方法 13.4 C十十异常处理基础:try、throw、catch 13.5 简单异常处理例子:除数为o 13.6 抛出异常 13.7 捕获异常 13.8 再抛出异常 13.9 异常指定 13.10 处理意外异常 13.11 堆栈解退 13.12 构造函数、析构函数与异常处理 13.13 异常与继承 13.14 处理new故障 13.15 auto_ptr类与动态内存分配 13.16 标准库异常层次 小结 术语 自测练习 自测练习答案 练习 第14章 文件处理 14.1 简介 14.2 数据的层次 14.3 文件和流 14.4 建立顺序访问文件 14.5 读取顺序访问文件中的数据 14.6 更新顺序访问文件 14.7 随机访问文件 14.8 建立随机访问文件 14.9 向随机访问文件中随机地写入数据 14.10 从随机访问文件中顺序地读取数据 14.11 实例研究:事务处理程序 14.12 对象的输入/输出 小结 术语 自测练习 自测练习答案 练习 第15章 数据结构 15.1 简介 15.2 自引用类 15.3 动态内存分配 15.4 链表 15.5 堆栈 15.6 队列 15.7 树 小结 术语 自测练习 自测练习答案 练习 特殊小节:建立自己的编译器 第16章 位、字符、字符串和结构 16.1 简介 16.2 结构的定义 16.3 结构的初始化 16.4 函数和结构 16.5 类型定义:typedef 16. 6 范例:高效的洗牌和发牌模拟程序 16.7 位运算符 16.8 位段 16.9 字符处理库 16.10 字符串转换函数 16.11 字符串处理库中的查找函数 16.12 字符串处理库中的内存函数 16.13 字符串处理库中的其他函数 小结 术语 自测练习 自测练习答案 练习 第17章 预处理器 17.1 简介 17.2 预处理指令#include 17.3 预处理指令#define:符号常量 17.4 预处理指令#define:宏 17.5 条件编译 17.6 预处理指令#error和#pragma 17.7 运算符#和## 17.8 行号 17.9 预定义的符号常量 17.10 断言(宏assert) 小结 术语 自测练习 自测练习答案 练习 第18章 C语言遗留代码问题 18.1 简介 18.2 UNIX和DOS系统中的输入/输出重定向 18.3 变长参数表 18.4 使用命令行参数 18.5 对编译多个源文件程序的说明 18. 6 用edt和atexit终止程序的执行 18.7 volatile类型限定符 18.8 整数和浮点数常量的后缀 18.9 信号处理 18.10 动态内存分配:函数calloc和realloc 18.11 无条件转移:goto语句 18.12 联合体 18.13 连接指定 小结 术语 自测练习 自测练习答案 练习 第19章 string类与字符串流处理 19.1 简介 19.2 string的赋值与连接 19.3 比较string 19.4 子串 19.5 交换string 19.6 string的特性 19.7 寻找string中的字符 19.8 替换string中的字符 19.9 在string中插入字符 19.10 转换成C语言式char 字符串 19.11 迭代器 19.12 字符串流处理 小结 术语 自测练习 自测练习答案 练习 第20章 标准模板库(STL) 20.1 标准模板库(STL)简介 20.1.1 容器简介 20.1.2 迭代器简介 20.1.3 算法简介 20.2 顺序容器 20.2.1 vector顺序容器 20.2.2 1ist顺序容器 20.2.3 deque顺序容器 20.3 关联容器 20.3.1 multiset关联容器 20. 3.2 set关联容器 20.3.3 mdtimap关联容器 20.3.4 map关联容器 20.4 容器适配器 20.4.1 stack适配器 20.4.2 queue适配器 20.4.3 Priority_queue适配器 20.5 算法 20.5.1 fill、fill_n、generate与generate_n 20.5.2 equal、mismatch和1exicographical_compare 20.5.3 remove、remove_if、 remove_copy和remove_copy_if 20.5.4 replace、replace_if、replace_copy和replace_copy_if 20.5.5 数学算法 20.5.6 基本查找与排序算法 20.5.7 swap、iter_swap和swap_ranges 20.5.8 copy—backward、 merge、 unique和reverse 20.5.9 inplace_merge、 unique—copy和reverse—copy 20.5.10 集合操作 20.5.11 1ower—bound、 upper—bound和equal_range 20.5.12 堆排序 20.5.13 min和max 20.5.14 本章未介绍的算法 20.6 bitset类 20.7 函数对象 小结 术语 自测练习 自测练习答案 练习 Internet和World Wide Web中的STL资源 STL文献 第21章 ANSI/ISO C++标准语言补充 21.1 简介 21.2 bool数据类型 21.3 static—cast运算符 21.4 const—cast运算符 21.5 reinterpret—cast运算符 21.6 名字空间 21.7 运行时类型信息(RTTI) 21.8 运算符关键字 21.9 explicit构造函数 21.10 mutable类成员 21.11 类成员指针(.和—>) 21.12 多重继承与virtual基类 21.13 结束语 小结 术语 自测练习 自测练习答案 练习 附录A 运算符的优先级与结台律 附录B ASCII字符集 附录C 数值系统 附录D 有关C++的Internet与Web资源 参考文献 【媒体评论】
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值