1.jinja2模板介绍和查找路径

from flask import Flask, render_template
import os

# 之前提到过在渲染模板的时候,默认会从项目根目录下的templates目录下查找模板
# 如果不想把模板文件放在templates文件夹下,那么可以在Flask初始化的时候指定
'''
Flask类的构造函数

    def __init__(
        self,
        import_name,
        static_url_path=None,
        static_folder='static',
        static_host=None,
        host_matching=False,
        subdomain_matching=False,
        template_folder='satori',
        instance_path=None,
        instance_relative_config=False,
        root_path=None
    ):
可以看到有一个template_folder='satori'
我们在初始化的时候可以重新指定
'''
BASE_DIR = os.path.dirname(__file__)
app = Flask(__name__, template_folder=os.path.join(BASE_DIR, "satori"))

@app.route(r"/satori")
def satori():
    return render_template("1.html")

if __name__ == '__main__':
    app.run(host="localhost", port=7777)

  

 

2.模板传参以及技巧

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>my name is {{name}}, age is {{age}}</h1>
</body>
</html>

  

from flask import Flask, render_template
app = Flask(__name__)

@app.route(r"/index")
def index():
    '''
    在html文件中,以{{}}定义,比如{{name}},然后在渲染模板的时候传参进去即可
    通过name="xxx"的形式,会自动进行替换。
    渲染的流程是先把html文件读取进来,再将{{}}里面的内容替换掉,因此最终返回给浏览器的内容是不包含{{}}的
    '''
    return render_template("1.html", name="satori", age=17)

if __name__ == "__main__":
    app.run(host="localhost", port=8888)

  

@app.route(r"/index")
def index():
    '''
    但是如果要替换的内容比较多的话,那么一个一个写的话,风格不是很pythonic
    因此我们会把内容都写在一个字典里,然后通过**传值
    '''
    replace_content = {"name": "mashiro", "age": 16}
    return render_template("1.html", **replace_content)

  

依旧可以打印出结果

既然如此的话,那么我们可不可以传入一个字典或者列表呢呢?然后按照key或者索引的方式呢?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <!--可以使用Python的语法d["xx"], 也可以使用d.xx-->
    <h2>my name is {{info['name']}}, age is {{info.age}}</h2>
    <h2>在{{arr}}中,数字1总共出现了{{arr.count(1)}}次</h2>
    <h2>另外两个花括号之间必须要写值,不能是空的花括号,否则报错</h2>
    <h2>但如果两个花括号中间的内容,我们在模板渲染的时候没有传值呢,那么不会显示,也不会报错</h2>
    <h2>比如下面的类容就不会显示,因为在render_template中没有mmp="xx"</h2>
    <h2>{{mmp}}</h2>

</body>
</html>

  

from flask import Flask, render_template
app = Flask(__name__)

@app.route(r"/index")
def index():
    '''
    但是如果要替换的内容比较多的话,那么一个一个写的话,风格不是很pythonic
    因此我们会把内容都写在一个字典里,然后通过**传值
    '''
    info = {"name": "matsuri", "age": 400}
    arr = [1, 1, 2, 3, 1, 1, 3]
    return render_template("1.html", info=info, arr=arr)

if __name__ == "__main__":
    app.run(host="localhost", port=8888)

3.模板中使用url_for的两种方式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2><a href="{{link}}">你想成为女装大佬吗?想搞基吗?想的话,就点击进入新世界的大门吧</a></h2>
</body>
</html>

  

from flask import Flask, render_template, url_for
app = Flask(__name__)

@app.route(r"/bili")
def bili():
    import requests
    content = requests.get("http://www.bilibili.com")
    content.encoding = content.apparent_encoding
    return content.text

@app.route(r"/gay")
def gay():
    return render_template("bilibili.html", link=url_for("bili"))

if __name__ == "__main__":
    app.run(host="localhost", port=8888)

  

  

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2><a href="{{ url_for('bili') }}">你想成为女装大佬吗?想搞基吗?想的话,就点击进入新世界的大门吧</a></h2>
</body>
</html>

  

from flask import Flask, render_template, url_for
app = Flask(__name__)

@app.route(r"/bili")
def bili():
    import requests
    content = requests.get("http://www.bilibili.com")
    content.encoding = content.apparent_encoding
    return content.text

@app.route(r"/gay")
def gay():
    # 替换之后,这里就不用传参了,因为在模板中可以直接获取链接
    return render_template("bilibili.html")

if __name__ == "__main__":
    app.run(host="localhost", port=8888)

  同样的结果

4.jinja2模板过滤器的基本使用

过滤器是通过管道符号|,来进行使用的,例如:{{name|length}},将返回name的长度。过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能再返回相应的值,之后再将结果渲染到页面中。jinja2内置了许多过滤器,下面来介绍一个常用的过滤器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>{{age|abs}}</h1>
</body>
</html>
@app.route(r"/filter")
def foo():
    # 这里传入一个负值
    return render_template("filter.html", age=-18)

  

5.default过滤器详解

之前我们说过,如果我们定义了一个{{mmp}},但是我们在视图函数的render_template中并没有传值,那么{{mmp}}在页面上是不会显示的,当然也不会报错。但是我们想,对于那些没有传值的变量,我们能不能给一个默认值呢?显然是可以的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>{{s1|default("这个人很懒,什么也没留下")}}</h2>
    <h2>{{s2|default("这个人很懒,什么也没留下")}}</h2>
</body>
</html>
@app.route(r"/signature")
def info():
    s1 = "一个人只要好好活着,就足以拯救某个人"
    return render_template("defualt.html", s1=s1)

  

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>{{s1}}</h2>
    <!--不过这里还有一个问题,那么如果我指定了s2=None,那么页面上就会显示None
        default是否执行,不在于你传的什么值,而在于你有没有传值,只要传了,就不会显示default的内容
        那如果我想,当传入空字符串,空字典等等,在Python中为False的值,还是执行default的内容,
        该怎么办呢?可以加入一个参数boolean=True,表示在Python中bool为False的值也会被包含在内-->
    <h2>{{s2|default("这个人很懒,什么也没留下", boolean=True)}}</h2>
    <!--如果s3为False,那么会自动选择"默认值",两种方式比较类似-->
    <h2>{{s3 or "默认值"}}</h2>
</body>
</html>

  

6.常用过滤器

escape:转义,默认是开启的。{{xxx|escape}}
那么如何关闭转义呢?这里要介绍一下{{}}和{% %},{{}}存放变量,{%%}执行逻辑
{% autoescape off %}
这里的标签是不会被转义的
{% endautoescape %}
safe:和escape相反,意思是安全的。{xxx|safe}也不会被转义
first:{xx|first},返回序列xx的第一个元素,我们也可以直接使用{{xx[0]}}
last:返回最后一个元素
length:返回序列的长度,sum:返回序列的总和
join:{xx|join(sep)},使用sep将序列xx拼接成一个字符串
int:转化为int
float:转化为float
string:转化为str
lower:小写
upper:大写
replace:{xx|replace(old, new)},将xx中old替换成new
truncate:{xx|truncate(length=14)},表示不管你输入多少字符,在页面上最多显示14和,剩下的用几个省略号表示
wordcounts:计算一个长字符串中某单词出现的次数

  

7.自定义过滤器

之前说过过滤器本质上就是个函数,因此我们只需要写个函数,定义相应的逻辑,然后把函数注册到jinja2过滤器当中即可 

我们手动实现以下replace过滤器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>{{s|屮艸芔茻}}</h2>
</body>
</html>

  

@app.route(r"/index")
def index():
    s = "hello satori"
    return render_template("default.html", s=s)
# 仅仅是这样是不起作用的,我们必须要将函数注册到jinja2过滤器当中
@app.template_filter(name="屮艸芔茻")  # 这里的name就是我们在html中使用的过滤器的名字
def cut_hello(string):
    return string.replace("hello", "")

  

8.自定义过滤器处理时间

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>hello 大家好 我是lex,,发表时间:{{time| handle_time}}</p>
</body>
</html>

  

@app.route(r"/status")
def publish():
    import datetime
    time = datetime.datetime(2018, 9, 24)
    return render_template("status.html", time=time)

@app.template_filter(name="handle_time")
def handle_time(time):
    from datetime import datetime
    if isinstance(time, datetime):
        now = datetime.now()
        # 更精确的话可以使用秒
        days = (now - time).days
        if days < 1:
            return "今天"
        elif days < 3:
            return "三天内"
        elif days < 7:
            return "一星期内"
        elif days < 30:
            return "一个月内"
        else:
            return "时间很久远了"
    else:
        # 返回的不是时间格式
        return time

  

9.if语句

和Python中的if语句类似,使用{%%}包裹,但是不要忘记结尾的{%endif%}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {% if gender == "f" %}
        <!--这里相当于Python的两层if循环-->
        {% if age >= 18 %}
        <h2>获取我们可以来一场交易</h2>
        {% else %}
        <h2>虽然担些风险但也值得一试</h2>
        {% endif %}
    {%else%}
        {% if age >= 18 %}
        <h2>我不搞基</h2>
        {% else %}
        <h2>可爱的男孩子也是可以的</h2>
        {% endif %}
    {%endif%}
</body>
</html>

  

@app.route(r"/deal")
def deal():
    return render_template("if.html", gender="f", age=16)

  

10.for语句

和Python里面for循环也基本一致,也别忘了结尾的{% endfor %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {% for age in ages %}
        <h2>{{age}}</h2>
    {% endfor %}

    <table border="1px solid red">
        <thead>
            <tr>
                <th>姓名</th>
                <th>出场动漫</th>
            </tr>
        </thead>
        <tbody>
            {% for name in girls %}
            <tr>
                <td>{{name}}</td>
                <td>{{girls[name]}}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
</body>
</html>

  

@app.route(r"/for")
def loop():
    ages = [17, 400, 20, 16, 14]
    girls = {"古明地觉": "东方地灵殿", "四方茉莉": "sola", "牧濑红莉栖": "命运石之门",
             "坂上智代": "Clannad", "神尾观铃": "air"}
    return render_template("for.html", ages=ages, girls=girls)

  

如果想反向遍历,只需要加上一个过滤器,xx|reverse,表示反向遍历xx

此外,jinja2还提供了索引

loop.index   当前迭代的索引(从1开始)

loop.index0  当前迭代的索引(从0开始)

loop.first  是否是第一次迭代,返回True或者False

loop.last  是否是最后一次迭代,返回True或者False

loop.length    序列的长度

我们对刚才的例子做一下修改

11.九九乘法表

在jinja2中,还可以使用range,接下来便实现一个九九乘法表

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <table border="1px">
        {% for i in range(1, 10) %}
        <tr>
            <!--此外还有一种方式,那就是jinja2中,for循环是可以带条件的,这句话还可以这么改-->
            <!--{#  {% for j in range(1, 10) if j < i %}, j也从1遍历到10,但必须满足j < i  #}-->
            <!--关于上面的{# #}在jinja中表示注释,html的注释没用,还是会被解释,必须要在模板语言两端加上{# #} -->
            {% for j in range(1, i) %}
                <td>{{j}} * {{i}} = {{i * j}}</td>
            {% endfor %}
        </tr>
        {% endfor %}
    </table>
</body>
</html>

  

@app.route(r"/nine9c法b")
def minus():
    return render_template("九九乘法表.html")

  

12.宏的概念和基本使用

宏,说的通俗一点,就类似于Python当中的函数,我们给一系列操作进行一个封装,再给一个名字。然后调用宏名的时候,就会执行封装的一系列操作。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <!--如何定义一个宏-->
    {% macro input(name, value="", type="text") %}
        <input type="{{type}}" name="{{name}}" value="{{value}}"/>
    {% endmacro %}
    <!--input就类似于函数名,这里叫什么无所谓。name是我们需要传的参数,value和type是缺省参数-->
    <!--当我们执行{#    {{input("satori", "love")}}    #}的时候,等价于<input type="text" name="satori" value="love"/>-->
    <form action="/show" method="post">
        {{input("satori","东方地灵殿")}}
        {{input("mashiro","樱花庄的宠物女孩")}}
        {{input("", "提交", "submit")}}
    </form>
</body>
</html>

  

from flask import Flask, render_template, request
app = Flask(__name__)

@app.route(r"/index")
def index():
    return render_template("1.html")

@app.route(r"/show", methods=["POST"])
def show():
    satori = request.form.get("satori")
    mashiro = request.form.get("mashiro")
    return f"satori come from {satori}, mashiro come from {mashiro}"

if __name__ == "__main__":
    app.run(host="localhost", port=8888)

  

  

13.宏的导入和注意事项

  宏也是可以导入的,在flask中,宏的导入和Python导入模块是类似的。话说为什么要有宏的导入,和Python中模块的导入是一致的。不然文件看起来很乱

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {% macro input(name, value="", type="text") %}
        <input type="{{type}}" name="{{name}}" value="{{value}}"/>
    {% endmacro %}
</body>
</html>

  我把之前定义的宏写在一个单独的文件里,导入通过import "宏文件的路径" as xxx, 通过xxx.宏名即可,这里必须要起名字

  或者from "宏文件的路径" import 宏名 [as xxx]

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <!--导入的同时指定一个别名-->
    {% import "macro.html" as macro  %}
    <form action="/show" method="post">
        <!--使用的时候直接通过marco.input即可。marco相当于模块,input相当于函数或者类-->
        {{macro.input("satori","东方地灵殿")}}
        {{macro.input("mashiro","樱花庄的宠物女孩")}}
        {{macro.input("", "提交", "submit")}}
    </form>
</body>
</html>

  

14.include标签使用

include的使用非常简单,直接导入就行了,{% include "xx.html" %},相当于 ctrl+c和ctrl+v

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>但使龙城飞将在</p>
</body>
</html>

  

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {% include "a.html" %}
    <p>不教胡马度阴山</p>
</body>
</html>

  

15.set和with语句以及模板中定义变量

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {% set username="satori" %}
    <!--set一旦设置了,那么在全局都可以使用-->
    <h2>{{username}}</h2>

    {% with username="koishi" %}
    <h2>{{username}}</h2>
    {% endwith %}
    <!--{#with一旦设置,那么设置的值只会在with语句块内生效,所以结尾才要有endwith构成一个快
    此外with还有另一种写法,那就是
    {% with %}
    {% set username = "koishi" %}
    {% endwith %}
    这样写也是没问题的,因为set在with里面 #}-->

    <h1>{{username}}</h1>
</body>
</html>

  

16.加载静态文件

需要在项目根目录下,创建一个static文件夹,当然也可以不叫static,但是flask默认叫static。当然我们也可以在创建app的时候单独指定static_folder,类似template_folder

p{
    color: aqua;
}

  

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{{url_for('static', filename='css/index.css')}}">
</head>
<body>
    <p>xxxxxxxxxxxxxxxx</p>
</body>
</html>

  

@app.route(r"/index")
def index():
    return render_template("index.html")

  

一句话总结:无论图片啊,js啊,还是css,都使用使用{{url_for('static', filename='css|js|images/xxx.xxx')}}

17.模板继承

之前介绍了include,但是还不够灵活,因为网站一大的话,那么重合的部分就会变多,因此使用include还不是一个最好的方式。接下来介绍的模板继承非常的灵活。可以想象一下,我们博客园,四周很多内容都是不变的,如果没来一个页面都要写一遍的话,会很麻烦。因此我们可以将不变的部分先写好,在变的部分留一个坑,这就是父模板。然后字模板继承的时候,会将父模板不变的部分继承过来,然后将变得部分,也就是父模板中挖的坑填好。总结一下就是:父模板挖坑,子模板填坑。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>なんでそんなになれてんだよ</p>
    <p>雪菜と何度もキースしたんだよ</p>
    {% block 冬马小三 %}
    {% endblock %}   <!--这两行便相当于我们在父模板中挖的坑-->
    <p>どこまで私を置いてきぼりに気が済むんだよ</p>
    {% block 雪菜碧池 %}
    {% endblock %}
    <p>最初私の前から消えたのはお前だろ</p>
    {% block 打死白学家 %}
    {% endblock %}
    <p>勝手に私の手が届けないところに行ったのはお前だろう</p>

</body>
</html>

 

{% extends "base.html" %}   <!--将父模板继承过来-->

<!--接下来填好我们在父模板中挖的坑,我们挖了三个,所以这里也应该要埋三个-->
{% block 冬马小三 %}
<h2>我爱小三</h2>
{% endblock %}

{% block 雪菜碧池 %}
<h2>我爱碧池</h2>
{% endblock %}

{% block 打死白学家 %}
<h2>打死春哥,悄悄抱走冬马和雪菜</h2>
{% endblock %}

  

@app.route(r"/dsxb")
def dsxb():
    return render_template("dsxb.html")

  

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <!--另外模板继承,如果父模板中挖的坑中,已经有内容了,那么子模板继承过来的时候会自动清除。-->
    <!--{#   如果想保留,需要加上{{super()}}    #}-->
    {% block 冬马小三 %}
    <p>我是父模板中的内容</p>
    {% endblock %}

    {% block 雪菜碧池 %}

    {% endblock %}

</body>
</html>

  

{% extends "base.html" %}

{% block 冬马小三 %}
{{super()}}
<h2>我是子模板中的内容</h2>
{% endblock %}

<!--{#  如果在一个块中,想使用另一个块的内容,可以通过{{self.块名()}}来实现   #}-->
{% block 雪菜碧池 %}
{{self.冬马小三()}}
{% endblock %}

  

注意:{% extend "xxx.html"  %}要放在最上面,不然容易出问题,在Django中是直接会报错的

另外,子模板中的代码一定要放在block语句块内,如果放在了外面,jinja是不会渲染的

2.jinja2的更多相关文章

  1. 自定义jinja2 过滤器

    今天,我们要讲的是自定义jinja2 过滤器这个知识点,因为官方文档对此一代而过,讲得不够清楚,所以我们专门拿出来讲一下. 例子 例子写了两个自定义过滤器,一个是转换字典到字符串的过滤器,一个是返回当 ...

  2. 在windows上如何安装python web引擎jinja2

    首先要把你的Python文件夹加到环境变量里头去.假设你的Python文件夹位于C:\Python34,那么你需要打开CMD并输入: SETX PATH "%path%;C:\Python3 ...

  3. SaltStack配置管理之状态模块和jinja2(五)

    官方文档 https://docs.saltstack.com/en/latest/topics/states/index.html 配置管理之SLS Salt  State  SLS描述文件(YAM ...

  4. Ansible用于网络设备管理 part 2 对Jinja2 YAML 和 module的理解

    虽然很不想用“应该”这个词,但是还是写上了,的确我自己目前就是这么理解的. 那么这个理解就是,Ansible的一个key point 就是总的一个playbook是去依赖很多元素的,就像一开始那个图里 ...

  5. Ansible用于网络设备管理 part 1 Jinja2 YAML初窥

    这一次的实验内容依然来自Kirk Byers的博客,源地址在https://pynet.twb-tech.com/blog/python/paramiko-ssh-part1.html 但是,这次实验 ...

  6. easy_install jinja2 mac linux

    error: can't create or remove files in install directory The following error occurred while trying t ...

  7. Flask 框架下 Jinja2 模板引擎高层 API 类——Environment

    Environment 类版本: 本文所描述的 Environment 类对应于 Jinja2-2.7 版本.   Environment 类功能: Environment 是 Jinja2 中的一个 ...

  8. jinja2 宏的简单使用总结(macro)

    Table of Contents 1. 简介 2. 用法 3. 参数和变量 4. 注意事项 4.1. macro的变量只能为如下三种: 4.2. 和block的关系: 5. 参考文档 1 简介 ji ...

  9. Jinja2学习笔记暨官方文档的翻译

    http://blog.csdn.net/lgg201/article/details/4647471 呵呵, 刚刚看完Python模板引擎Jinja2的文档, 感觉很好, 觉得动态语言真是很好.  ...

  10. Jinja2模版语言自定义filter的使用

    Jinja2模版语言,自带有一些filter,能够在前端的模版中控制数据按照相应的方式显示.比如以下两种filter,分别能在前端控制数字的近似精度显示和根据字符串长度补齐: round(value, ...

随机推荐

  1. Leetcode 684.冗余连接

    冗余连接 在本问题中, 树指的是一个连通且无环的无向图. 输入一个图,该图由一个有着N个节点 (节点值不重复1, 2, ..., N) 的树及一条附加的边构成.附加的边的两个顶点包含在1到N中间,这条 ...

  2. BZOJ 2756 SCOI2012 奇怪的游戏 最大流

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2756 Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N ...

  3. STL应用——hdu1412(set)

    set函数的应用 超级水题 #include <iostream> #include <cstdio> #include <algorithm> #include ...

  4. Android java.lang.NoClassDefFoundError的错误

    在开发过程中,遇到一个这样的问题:java.lang.NoClassDefFoundError: android.support.v4.util.SparseArrayCompat,这个问题很奇怪,J ...

  5. PAT 甲级 1042 Shuffling Machine

    https://pintia.cn/problem-sets/994805342720868352/problems/994805442671132672 Shuffling is a procedu ...

  6. x86/x64的stack*****************************TBD

    1.push parameter, %rdi,%rsi,%rdx,%rcx,%r8,%r9 用作函数参数,依次对应第1参数,第2参数... 2. push return address 3. push ...

  7. HL7 2.6 解析(XML)

    用途:检验化验(LIS)实验室设备数据交换解析. using System; using System.Collections.Generic; using System.Text; using Sy ...

  8. ElasticSearch1.7.1拼音插件elasticsearch-analysis-pinyin-1.3.3使用介绍

    ElasticSearch拼音插件elasticsearch-analysis-pinyin使用介绍 https://my.oschina.net/xiaohui249/blog/214505 摘要: ...

  9. BZOJ4484 JSOI2015最小表示(拓扑排序+bitset)

    考虑在每个点的出边中删除哪些.如果其出边所指向的点中存在某点能到达另一点,那么显然指向被到达点的边是没有用的.于是拓扑排序逆序处理,按拓扑序枚举出边,bitset维护可达点集合即可. #include ...

  10. MFC 相关类、函数

    timeSetEvent()函数 CRectTracker类的使用 SetLocalTime设置本地时间 AdjustTokenPrivileges启用权限