图论刷题整理

图论习题整理

求先序排列

需要知道树的遍历方法,分别前中后序,代表着先访问根节点,左子树,右子树,或是左中右,或是左右中

现在给同一棵树的中后两个序列,求前序,

首先清楚这样的性质:

1.对于某个树(无论是子树还是本体,只要是棵完整的树就行),其前序遍历序列的第一个节点肯定是它的根,就是对于节点,其位于的层数越浅越靠后

对于后序遍历也类似,只是相反

2.中序遍历虽然看起来很乱,啥用没有,但是它在划分子树(是左子树还是右子树)上有着不可或缺的作用,毕竟对于一个数的中序序列,一旦找到根节点,其左子树和右子树就非常好确定了

3.因为无论哪种遍历,都是挨个按照子树的顺序去遍历的,所以子树的序列在总序列里面一定是连续的,不存在穿插的情况

那么这就好办了,递归处理规定区间的序列就好

先将后序序列中最后一位取出,在中序序列中进行查找,然后规定中序序列的左右子树,也就是下一步的目标,进行递归处理

同时,我们注意到中序遍历和后序遍历的子树区间并不对应,所以要同时处理两个序列需要处理的区间,中序好说,关键是后序

我们发现对于后序序列,其构成一定为:(左子树)+(右子树)+(根节点)

就是一定是这样有序的

那么只要处理出区间长度(就是子树大小,当然左右需要分开的),差不多这题就结了,

记得我们在处理中序序列时找的根节点吗?就用它的下标来作区间处理

这里的区间表示有点考验思维,建议自己推(不推反正下面也有代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
char tar1[10];
char tar2[10];
int len;
inline int find(const char &x){
    for(int i=1;i<=len;i++)
        if(tar1[i]==x) return i;
}
inline void search(int l1,int r1,int l2,int r2){
    printf("%c",tar2[r2]);
    int t=find(tar2[r2]);
    if(t>l1) search(l1,t-1,l2,r2+t-r1-1);
    if(t<r1) search(t+1,r1,l2+t-l1,r2-1);
}
int main(){
    scanf("%s",tar1+1);
    scanf("%s",tar2+1);
    len=strlen(tar1+1);
    search(1,len,1,len);
    return 0;
}

没有与最短路及其算法相关的图论整理博客不是好博客(本来就不是

虫洞Wormholes

题目翻译:

给了一堆数据范围(题目中的小路不会耗10000秒什么的也是数据范围啦...)

然后问你有没有负环

(我兴致冲冲想写最短路你给我看这个?

看到题,看到环,不要什么时候都想着tarjan...tarjan只是存强连通分量的算法,虽然环也可以,但是用于找负环...有SPFA为什么不用呢?

SPFA基于广搜BFS,深搜DFS当然可以过但是对于那道负环模板题就会被卡掉

为什么SPFA(或者Bellman-Ford)会被负环卡掉?

因为SPFA见到可以更新到很小,就一定会进行更新和入队(准备下一步松弛)

那么负环正是可以"无限缩小"的这么一种东西,就这样,SPFA在无限的更优方案中死掉了

每一个点只要入队超过n-1次,就说明有负环,因为每个店最多被其他每个点各松弛一次,多了就是在里面绕起来了,用它判负环就是了

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int t;
int n,m;
struct Ed{
    int to,nxt,dis;
}ed[50005];
int head[20005];
bool vis[20005];
int tms[20005];
int ednum;
inline void add(const int &from,const int &to,const int &dis){
    ed[++ednum].to=to;
    ed[ednum].dis=dis;
    ed[ednum].nxt=head[from];
    head[from]=ednum;
}
int dis[20005];
queue<int> q;
inline bool spfa(){
    memset(dis,0x3f,sizeof dis);
    memset(vis,0,sizeof vis);
    memset(tms,0,sizeof tms);
    dis[1]=0;
    vis[1]=1;
    tms[1]++;
    q.push(1);
    while(!q.empty()){
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];i;i=ed[i].nxt){
            if(dis[ed[i].to]>dis[u]+ed[i].dis){
                dis[ed[i].to]=dis[u]+ed[i].dis;
                if(!vis[ed[i].to]){
                    q.push(ed[i].to);
                    vis[ed[i].to]=1;
                    tms[ed[i].to]++;
                    if(tms[ed[i].to]>=n)
                        return 1;
                }
            }
        }
    }
    return 0;
}
int main(){
    scanf("%d",&t);
    while(t--){
        memset(ed,0,sizeof ed);
        memset(head,0,sizeof head);
        ednum=0;
        int w;
        scanf("%d%d%d",&n,&m,&w);
        for(int i=1;i<=m;i++){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
            add(b,a,c);
        }
        for(int i=1;i<=w;i++){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,-c);
        }
        bool ok=spfa();
        if(ok) printf("YES\n");
        else printf("NO\n");
    }return 0;
}

原文地址:https://www.cnblogs.com/648-233/p/11346941.html

时间: 2024-10-17 07:16:41

图论刷题整理的相关文章

并查集刷题整理

并查集刷题整理 并查集是一种数据结构,然而用于维护其的数组及函数又极少,用途极为广泛,被广泛地应用于极多的综合题目, 比较经典的应用就是最小生成树\(kruskal\)算法 T1:Watering Hole G 题意 \(n\)个牧场,需要挖井,在第\(i\)号农场挖需要\(W_i\)元,在\(i\)与\(j\)号之间通水需要\(P_{i,j}=P_{j,i}\)元,问最小花费. 思路: 显然这并不是最短路问题,是最小生成树问题,目的就是将所有农场通过花费最小的路径进行串通 对于"挖井"

刷题&amp;考试整理

date:19/03/05 今天没有考试,花一天学习了一下SAM (其中睡了半天的觉) 过于颓废的一天...... 我觉得我还是太不紧张了quq 不过好消息是在几位dalao的帮助下建好了blog 这段时间的各种计划与刷题记录还有自己的整理大概都会丢上来 这几天计划改在SDFZ时的遗留题目 似乎三道里两道反演 ? 改完了就写总结XD list: 1-20:T3 1-25:T1 1-28:T3 原文地址:https://www.cnblogs.com/Pump-six/p/10479600.htm

两个月刷400道leetcode之后的经验与心得总结、真题整理分享

前言 随着互联网寒潮的到来, 越来越多的互联网公司提高了面试的难度,其中之一就是加大了面试当中手撕算法题的比例.这里说的算法题不是深度学习,机器学习这类的算法,而是排序,广度优先,动态规划这类既考核数据结构也考核编程能力的题目.刷题的网址非常的多,其中以leetcode是最为出名的. 在刷题上,我花了大量的时间,蹚了许多的坑,总结了一下,主要有这三个问题: 刷过的题老是忘,第二次刷的时候还是不会做 刷题的速度很慢,即使花一天时间,也常常只能刷五六道 坚持不下来,老是刷到一半就停滞下来了,当我第二

半个暑假的刷题有感

这半个多月一来,主要是在刷DP.开始是一些简单的DP(可是我没有感觉有多简单=_=!!),然后是最大连续子序列,最大公共子序列,最大子矩阵等等,这些题目还好,有的题目甚至可以模板化. 还有一些没有解决的难题: 1024 Max Sum Plus Plus 最大m段不重叠子段和](可不连续)1244 Max Sum Plus Plus Plus [最大m段不重叠子段和](连续) 1074 Doing Homework [压缩dp](这个题整个程序都在用位运算,让我这个小白情何以堪啊) 还有记忆化搜

7、8月刷题总结

准备开学了囧,7.8月刷题记录,以后好来复习,并且还要好好总结! 数据结构: splay: [BZOJ]1503: [NOI2004]郁闷的出纳员(Splay) [BZOJ]1269: [AHOI2006]文本编辑器editor(Splay) [BZOJ]1507: [NOI2003]Editor(Splay) treap: [BZOJ]1862: [Zjoi2006]GameZ游戏排名系统 & 1056: [HAOI2008]排名系统(treap+非常小心) [BZOJ]3224: Tyvj

今日刷题集合

月考没考,最皮的是刷题效率低的可怕,搜索中的那些回溯用的还是很水,不如总结一下. codevs 题号:1501 1506 1842 1983 2549 2806 3143 3145 1008 1294 1295 1501 二叉树的最大宽度和高度(没加using namespace std ;会过不去编译,max.min函数封装在#include<iostream>里,所以没有using namespace std ;不行.) 1 #include<bits/stdc++.h> 2

软考学习如何刷题

刷题是用最短的时间读懂题目和问题,并且理清思路,短时间接触大量各种题型的方法.不光要把题做会,而且还要把自己会做的题练熟,熟能生巧,对于培养"题感",是很有意义的.具体到备考中的刷题,作者给出几种刷题策略. (1) 计时刷题 把历年考题顺利打乱,随机抽取出15-40道题,进行短时间刷题考试,并记录答题时间.考生刷题时不仅要提高正确率,还要关注做题时间,要求考生快速读题.审题及答题.目的是锻炼速度,提高敏捷能力.计时刷题具有用时短,方便锻炼的特点,参加工作的考生可在工作之余进行刷题,高效

DP刷题记录

目录 dp刷题记录 codeforces 706C codeforces 940E BZOJ3997 POJ2279 GYM102082B GYM102082D codeforces132C L3-020 至多删三个字符 牛客 553C Chino with Queue POJ3260 The Fewest Coins Codeforces 372C dp刷题记录 codeforces 706C 题意:给出n个字符串,可以对每个字符串进行翻转操作, 每个操作对应一个消耗c[i],问经过操作后是否

LeetCode开心刷题五十六天——128. Longest Consecutive Sequence

最近刷题进展尚可,但是形式变化了下,因为感觉眼睛会看瞎,所以好多写在纸上.本来想放到文件夹存储起来,但是太容易丢了,明天整理下,赶紧拍上来把 今晚是周末,这一周都在不停的学学学,我想下周怕是不能睡午觉了,中午回去床对我的诱惑太大了,我得想办法,一进门先把被褥收起来,再放个欢快的歌,中午少吃点,加油小可爱 之前欠下的烂帐,把太多简单题做完,导致剩下的都是难题,所以万万记住一点捷径都不要走 128看花花酱大神的解法,发现对hashtable的了解十分不足,甚至一些常见函数都不知道是干什么的 这道题涉