图的存储:
- 邻接矩阵
- 邻接链表
- 链式前向星 = 边集数组+邻接表
链式前向星代码,维护一个head头数组,以及一个edges[]边数组。
链式前向星可以快速访问一个节点的所有邻近节点,在算法竞赛中广泛使用。链式前向星有两种写法,一种是struct,一种是三个数组head[]、next[]、to[].
/* 链式前向星 */
#include
#include
using namespace std;
const int maxn=500+5, maxe=100000+1;
int n, m, cnt;
int head[maxn]; // 头节点数组 保存节点
struct node{
int to, next, w; // to 表示到达的节点 next表示下一个节点 w表示权重
}edge[maxe]; // 边集数组
void add(int u, int v, int w){ // 添加一条边 头插法 无向图就是输入两遍 add(u, v, w) add(v, u, w)
edge[cnt].to = v;
edge[cnt].w =w;
edge[cnt].next = head[u];
head[u] = cnt++; // 给head[u]复制过后,然后在使得cnt++,边计数
}
void printg(){
for(int u=1; u" << i << ":(" << edge[i].to << " " << edge[i].w << " " << edge[i].next << ")";
}
cout << endl;
}
}
int main(){
freopen("test.txt", "r", stdin);
cin >> n >> m; // n:节点数 m:边数
cnt = 0; // 边从0来计数
memset(head, -1, sizeof(head)); // 初始给handj数组赋值为-1, -1表示没有下一条节点
int u, v, w;
for(int i=1; i<=m; i++){ // m条边
cin >> u >> v >> w;
// 无向图添加两边
add(u, v, w); //两条边
add(v, u, w);
}
printg();
return 0;
}
4 5
1 2 5
1 4 3
2 3 8
2 4 12
3 4 9
https://www.luogu.org/problem/P3916
数组控制:
/* 没有定义结构体,定义的是数组 next[maxn], to[maxn] */
#include
using namespace std;
const int maxn = 100000+5;
int n, m, x, y, total;
int maxx[maxn], head[maxn], nextn[maxn], to[maxn];
// maxx:记录每个点能够到达的最大点 head:头节点 next:每个节点能够到达的下一个节点 to:能够到达的邻接点
void add(int u, int v){ // 添加一条u---v的边
nextn[++total] = head[u]; // next从1开始d
head[u] = total;
to[total] = v;
}
void dfs(int u, int v){
if(maxx[u])
return;
maxx[u] = v;
// 访问u节点的所有邻接点
for(register int e=head[u]; e; e=nextn[e]){
if(!maxx[to[e]])
dfs(to[e], v);
}
// register修饰符暗示编译程序相应的变量将被频繁地使用,如果可能的话,应将其保存在CPU的寄存器中,以加快其存储速度
}
int main(){
freopen("test.txt", "r", stdin);
cin >> n >> m;
total = 0;
for(int i=1; i<=m; i++){
cin >> x >> y;
add(y, x); // 添加反向边
}
// 从每个节点出发
for(int i=n; i; i--){ // 倒序深度遍历
dfs(i, i);
}
for(int i=1; i<=n; i++){
if(i!=1) // 控制输出:第一个数前面没有空格,后面的数前面都有空格
cout << " ";
cout << maxx[i];
}
return 0;
}
结构体控制:
#include
#include
using namespace std;
const int maxn = 100000+5;
int n, m, x, y, total;
int maxx[maxn], head[maxn];
struct node{
int to;
int next;
}edge[maxn];
void add(int u, int v){
edge[total].to = v;
edge[total].next = head[u];
head[u] = total;
total++;
}
void printg(){
for(int u=1; u<=n; u++){
cout << u << " ";
for(int i=head[u]; i!=-1; i=edge[i].next){ // head[u] 第一条边 判断head[u]不等于-1
cout << "--->" << i << ":(" << edge[i].to << " " << edge[i].next << ")";
}
cout << endl;
}
}
void dfs(int index, int targ){
// cout << index << " " << targ << endl;
if(maxx[index])
return;
maxx[index] = targ;
for(int i=head[index]; i!=-1; i=edge[i].next){
// cout << head[index] << endl;
// cout << i << endl;
// cout << edge[i].to << endl;
if(!maxx[edge[i].to])
dfs(edge[i].to, targ);
}
}
int main(){
freopen("test.txt", "r", stdin);
cin >> n >> m;
total = 0;
memset(head, -1, sizeof(head));
for(int i=1; i<=m; i++){
cin >> x >> y;
add(y, x);
}
// printg();
for(int i=n; i>0; i--){
dfs(i, i);
}
for(int i=1; i<=n; i++){
if(i!=1)
cout << " ";
cout << maxx[i];
}
return 0;
}
字符串 子串树
#include
#include
#include
using namespace std;
const int maxn= 100+10, maxe=(maxn-1)*maxn/2;
string s;
int n;
struct node{
int to; // 到达的节点,该节点
int next; // 下一条跳节点
}edge[maxe];
int head[maxn];
int cnt;
void add(int u, int v){ // 从u到v
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt;
cnt++;
}
void printg(int k, int n){
for(int u=k; u" << i << ":(" << edge[i].to << " " << edge[i].next << ")";
}
cout << endl;
}
}
string sub_str;
void dfs(int index){
// cout << index;
sub_str += char(index+'a');
if(head[index] == -1){
cout << sub_str << endl;
sub_str = sub_str.substr(0, sub_str.length() - 1); // 去除最后一个字符
}
for(int i=head[index]; i!=-1; i=edge[i].next){
dfs(edge[i].to);
}
}
int main(){
freopen("test.txt", "r", stdin);
cin >> s;
n = s.length();
for(int k=0; k
判断子串是否回文
#include
#include
#include
using namespace std;
const int maxn= 100+10, maxe=(maxn-1)*maxn/2;
string s;
int n;
struct node{
int to; // 到达的节点,该节点
int next; // 下一条跳节点
}edge[maxe];
int head[maxn];
int cnt;
void add(int u, int v){ // 从u到v
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt;
cnt++;
}
void printg(int k, int n){
for(int u=k; u" << i << ":(" << edge[i].to << " " << edge[i].next << ")";
}
cout << endl;
}
}
string sub_str;
bool huiwen(string str){
for(int i=0; i> s;
n = s.length();
for(int k=0; ki; j--) //for(int j=i+1; j
https://www.nowcoder.com/practice/5bfb74efcd5449e69a480550b1fef431?tpId=98&tqId=32846&tPage=1&rp=1&ru=/ta/2019test&qru=/ta/2019test/question-ranking
只能过60%的测试样例
您的代码已保存
段错误:您的程序发生段错误,可能是数组越界,堆栈溢出(比如,递归调用层数太多)等情况引起
case通过率为66.67%
#include
#include
#include
using namespace std;
const int maxn= 100+10, maxe=(maxn-1)*maxn/2;
string s;
int n;
struct node{
int to; // 到达的节点,该节点
int next; // 下一条跳节点
}edge[maxe];
int head[maxn];
int cnt;
int max_len=0;
void add(int u, int v){ // 从u到v
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt;
cnt++;
}
void printg(int k, int n){
for(int u=k; u" << i << ":(" << edge[i].to << " " << edge[i].next << ")";
}
cout << endl;
}
}
string sub_str;
bool huiwen(string str){
for(int i=0; i> s;
n = s.length();
for(int k=0; ki; j--) //for(int j=i+1; j1){
break;
}
// cout << endl;
}
return 0;
}
但是自己还是很开心,写了链式前向星的代码,完成了一些突破。
综合来说,dp还是大杀器,要好好学习。之后也会更些dp的代码