有向图的强连通分量

强联通:两个点之间可以互相到达

如果某个图任意两个点都是强联通的,那么称这个图强联通

如果一个图的子图是强联通的,那么称这个图是强联通子图

一个图的极大强联通子图被称作强连通分量

有强联通分量意味着环

例:受欢迎的牛

如果有环,意味着这个环里的牛都互相喜欢

我们可以先求出环,然后把每一个环都看作一个点,这样整个图就变成了一个DAG(有向无环图)

看有几个点出度为0,如果大于一个点没有出边,就说明没有最受欢迎的牛

如果只有一个,那么强联通分量的大小就是答案

void tarjan(int u){
dfn[u]=++ind;
low[u]=dfn[u];
s[top++]=u;
in[u]=;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(dfn[v]==){//mei bian li dao, v zai zi shu li mian
tarjan(v);
low[u]=min(low[u],low[v]);
}else{//bian li dao le, v bu zai zi shu li mian
if(in[v]){//zai zhan li mian
low[u]=min(low[u],dfn[v]);
}
}
}
if(dfn[u]==low[u]){//fa xian scc
cnt_scc++;
while(s[top]!=u){//bu duan chu zhan
top--;
in[s[top]]=;
scc[s[top]]=cnt_scc;
}
}
}

完整代码:

#include<bits/stdc++.h>
using namespace std; int n,m; int cnt,head[]; struct edge
{
int to,nxt;
}edg[]; inline void add(int from,int to)
{
edg[++cnt].to=to;
edg[cnt].nxt=head[from];
head[from]=cnt;
} int dfn[],low[],ind,in[];
int s[],top;
int cnt_scc;
int scc[],cntscc[]; void tarjan(int x)
{
dfn[x]=++ind;
low[x]=dfn[x];
s[top++]=x;
in[x]=;
for(int i=head[x];i;i=edg[i].nxt)
{
int v=edg[i].to;
if(!dfn[v])
{
tarjan(v);
low[x]=min(low[x],low[v]);
}
else
{
if(in[v])
{
low[x]=min(low[x],dfn[v]);
}
}
}
if(dfn[x]==low[x])
{
cnt_scc++;
while(s[top]!=x)
{
top--;
in[s[top]]=;
scc[s[top]]=cnt_scc;
cntscc[cnt_scc]++;
}
}
} int out[];
int ans; int main()
{
scanf("%d%d",&n,&m);
for(int i=,x,y;i<=m;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
}
for(int i=;i<=n;i++)
{
if(!dfn[i]) tarjan(i);
}
for(int i=;i<=n;i++)
{
for(int j=head[i];j;j=edg[j].nxt)
{
int k=edg[j].to;
if(scc[i]!=scc[k]) out[scc[i]]++;
}
}
for(int i=;i<=cnt_scc;i++)
{
if(!out[i])
{
if(!ans)
ans=i;
else
{
cout<<;
return ;
}
}
}
cout<<cntscc[ans];
}

求强联通分量:

首先想到dfs,我们不妨先看看dfs数

发现有向图中dfs树会有横叉边

显然的事实:一个强连通分量一定是dfs树上的连续的一块

我们定义两个数组

dfn[x]表示x是第几个被dfs到的数(时间戳)

low[x]表示当前节点以及他的子树所有出边所能连到的dfn值中最小的一个

如果某一个点的low和他的dfn相同,就意味着出现强联通分量,就把这个强连通分量拿去(没了)

用一个栈来实现,寻找low时只在栈里面找,弹出时不断从栈顶弹出直到弹出这个点

A gift

把g按照升序排序,枚举g0,跑最小生成树(然后就tle)O(m^2logm)

当我们再连一条新边时,会出现环,所以找到环上的最大的边然后删掉它,复杂度O(n)

总复杂度O(mn)

狼抓兔子

平面图的最小割等于对偶图的最短路

最小割:所有割中边权和最小的割

对偶图:边变成点,点变成边    平面图的每一个块变成一个点,每一条边变成垂直的一条边

#include<cstdio>
#include<cstring>
#define oo 0x3f
#define MAXN 2000001
using namespace std;
struct edge {
int v,to,next;
} e[MAXN*];
int dis[MAXN],q[MAXN],head[MAXN];
bool tag[MAXN];
int n,m,ne,x;
void insert(int u,int v,int w) {
ne++;
e[ne].to=v;
e[ne].next=head[u];
e[ne].v=w;
head[u]=ne;
}
void spfa() {
memset(dis,oo,sizeof(dis));
int t=,w=;
tag[]=;
q[w]=;
dis[]=;
while(t!=w) {
int u=q[t++];
tag[u]=;
if(t==MAXN) t=;
for(int i=head[u]; i; i=e[i].next) {
int v=e[i].to;
if(dis[v]>dis[u]+e[i].v) {
dis[v]=dis[u]+e[i].v;
if(tag[v]==) {
q[w++]=v;
tag[v]=;
if(w==MAXN) w=;
}
}
}
}
}
int main() {
scanf("%d%d",&n,&m);
int nm=(n*m-n-m+)<<;
for(int i=; i<=n; i++) {
for(int j=; j<m; j++) {
scanf("%d",&x);
if(i==) insert(j,nm+,x);
else if(i==n) insert(,(((n-)<<)-)*(m-)+j,x);
else insert(((i-)<<)*(m-)+j,(((i-)<<)-)*(m-)+j,x);
}
}
for(int i=; i<n; i++) {
for(int j=; j<=m; j++) {
scanf("%d",&x);
if(j==) insert(,((i<<)-)*(m-)+,x);
else if(j==m) insert(((i<<)-)*(m-),nm+,x);
else insert(((i-)<<)*(m-)+j-,((i<<)-)*(m-)+j,x);
}
}
for(int i=; i<n; i++) {
for(int j=; j<m; j++) {
scanf("%d",&x);
insert((((i-)<<)+)*(m-)+j,((i-)<<)*(m-)+j,x);
}
}
spfa();
printf("%d\n",dis[nm+]);
return ;
}

奶牛的旅行

0/1分数规划

二分答案+spfa判负环

最优比率生成树

抢掠计划

把强联通分量缩点

从点1开始跑一遍最长路spfa,在酒吧取max

奶牛接力跑

倍增floyd(floyd快速幂)

g[1][i][j]表示从i到j只经过一条边的最短路

如何转移到g[2][i][j]?

枚 举所有中点k,对于所有的k,g[2][i][j]表示min(g[1][i][k]+g[1][k][j])

同理也可以求出g[4][i][k]

所以g[p][i][j]=min(g[p/2][i][k]+g[p/2][k][j])

g[3][i][j]=min(g[2][i][k]+g[1][k][j])

和快速幂的关系:用类似于快速幂的方法将其分解

while(b){
if(b&){
memset(f,0x3f,sizeof(f));
for(int k=;k<=n;k++){
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
f[i][j]=min(f[i][j],ret[i][k]+g[k][j]);
}
}
}
memcpy(ret,f,sizeof(f));
}
memset(f,0x3f,sizeof(f));
for(int k=;k<=n;k++){
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
f[i][j]=min(f[i][j],g[i][k]+g[k][j]);
}
}
}
memcpy(g,f,sizeof(f));
   b>>=1;
} print(ret[S][E])

Destroying road

  1. 两条最短路不交叉  删掉的边的数量:m-dis[s1][t1]-dis[s1][t2]
  2. 两条最短路有公共部分

Bfs求最短路

匈牙利算法:配对

int g[N][N];
int lk[N];// mei zi xi huan na ge nan de
bool vis[N];//zhe yi lun, mei zi you mei you bei jiao huan bool find(int x){
for(int i=;i<=n;i++){
if(!vis[i]&&g[x][i]){
vis[i]=;
if(lk[i]==||find(lk[i])){
lk[i]=x;
return ;
}
}
}
return ;
} for(int i=;i<=n;i++){
memset(vis,,sizeof(vis));
if(find(i)){
hunpei++;
}else{
break;
}
}

差分约束系统

最小化最长路

例题:糖果

qbzt day4 下午的更多相关文章

  1. Day4下午解题报告

    预计分数:30+30+0=60 实际分数:30+30+10=70 稳有个毛线用,,又拿不出成绩来,, T1 https://www.luogu.org/problem/show?pid=T15626 ...

  2. Day4下午

    不会啊. T1 找规律: 辗转相减,加速. #include<iostream> #include<cstring> #include<cstdio> #inclu ...

  3. qbzt day6 下午 模拟赛

    我太菜了 T2 给定一张有向图,每个点有点权.试找到一条路径,使得该路径上的点权最 大值减去点权最小值最大,问这个差最大是多少.   话说这个题第一个想到的思路是tarjan缩点+拓扑排序来着... ...

  4. qbzt day5 下午

    农场主John新买了一块长方形的新牧场,这块牧场被划分成M行N列(1 ≤ M ≤ 12; 1 ≤ N ≤ 12),每一格都是一块正方形的土地.John打算在牧场上的某几格里种上美味的草,供他的奶牛们享 ...

  5. qbzt day4 上午

    图论 最短路:dijkstra   spfa   floyd 最小生成树:kruskal 连通性:bfs/dfs    tarjan(强连通分量) 其它:拓扑排序    LCA 齿轮: 图的dfs树只 ...

  6. qbzt day3 下午(好难)

    内容提要 有关数据结构的例题 求逆序对数 统计每个数前面有多少比他大的数 开数组表示这个数之前0~9这些数出现了几次 动态将某个点加一,动态求前缀和 用树状数组 如果数太大了怎么办? 离散化 步骤:先 ...

  7. qbzt day2 下午

    内容提要 高精 矩阵 筛法 先是高精除法 注意细节 高精度开方:神奇的竖式 以小数点为分界线,每两个位砍一刀 87654.321-->08|76|54|.32|1 大概就是先对第一位开方,然后相 ...

  8. WC2017 游记

    你若安好,便是晴天. 其实本来是有一个写的比较详细的游记的……然而后来给断了,懒得补上了,简单一点好了. Day 0 早早爬起来去赶高铁…… 路上没太多可以写的……坐高铁的时候想起来了一些不开心的事情 ...

  9. Alpha冲刺! Day4 - 磨刀

    Alpha冲刺! Day4 - 磨刀 今日已完成 晨瑶:和大家交流了一下,反思这阶段团队遇到的问题. 昭锡:今天跟学长交流了点问题,学习了Gson使用. 永盛:Gravel 数据库重新设计. 立强:看 ...

随机推荐

  1. HNUSTOJ-1258 Time

    1258: Time 时间限制: 1 Sec  内存限制: 128 MB提交: 16  解决: 11[提交][状态][讨论版] 题目描述 Digital clock use 4 digits to e ...

  2. linux下装python3以及pip3

    1.wget https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tgz 2.tar zxvf Python-3.6.0.tgz 3.cd Pyt ...

  3. SpringBoot_03mybatisPlus

    注意: mybatisPlus默认加载resources下的mapper文件夹下的xml文件 默认将数据库表的字段用驼峰标识转换成实体类的属性 官方网站: https://mp.baomidou.co ...

  4. Show Profile

    1.是什么:是mysql提供可以用来分析当前会话中语句执行的资源消耗情况.可以用于SQL的调优的测量 2.官网:http://dev.mysql.com/doc/refman/5.7/en/show- ...

  5. nohup - 使程序运行时不挂起, 不向 tty 输出信息

    总览 (SYNOPSIS) nohup COMMAND [ARG]... nohup OPTION 描述 (DESCRIPTION) 执行 COMMAND 命令, 忽略 hangup (挂起) 信号. ...

  6. 最小可观(Minimal Observability Problem in Conjunctive Boolean Networks)

    论文链接 1. 什么是 conjunctive Boolean network (CBN) 仅仅包含and运算. 下面这个式子为恒定更新函数 2. 什么是可观 定义在时刻k是CBN的状态为 X(k) ...

  7. macOS安装wget

    brew install wget 或者 curl -O http://ftp.gnu.org/gnu/wget/wget-1.13.4.tar.gz tar xzvf wget-1.13.4.tar ...

  8. Linux下Centos7对外开放端口

    转载:https://blog.csdn.net/realjh/article/details/82048492 命令集合: ()查看对外开放的端口状态 查询已开放的端口 netstat -anp 查 ...

  9. Zookeeper学习笔记(上)

    Zookeeper学习笔记 本篇主要是一些基本的介绍和API的使用介绍, 有些只是记录了知识点,而没有完全在笔记中详细解释, 需要自行查找资料补充相关概念 主要参考了课程中的内容: Zookeeper ...

  10. Maven高级

    第一章 Maven解决冲突的方式 1.1 第一声明者优先原则 那个jar包的坐标在pom.xml文件上属于靠上的位置,这个jar包就是先声明的.先声明的jar包坐标下的依赖包,可以优先进入项目中. 示 ...