zoukankan      html  css  js  c++  java
  • Graph & Tree2

    https://www.cnblogs.com/tyqtyq/p/9769817.html


    0x65

    负环

    • SPFA
    • 当一个节点入队次数到达N的时候,就说明有负环
    • 或者记录最短路包含的路径条数
    • 还有其他优化手段,如将SPFA的队列换成栈,使用dfs等等

    差分约束系统

    • 特殊的不等式组,有N个不等式
    • 任意不等式都是形如这样的:(X_{i} - X_{j} leq c_{k})
    • 我们就可以建一张图使得对于任意不等式(X_{i} - X_{j} leq c_{k}),在i,j之间连一条长度为(c{k})的边
    • 那么我们求解单源最短路,(X_{i} = dist_{i})就是一组解
    • 但是为了保证图的联通性,应该加一个虚拟节点(X_{0})使得其到所有节点距离为0,从(X_{0})开始跑SPFA就可以求出解了
    • 如果有负环则无解

    0x66

    卡了我几天的tarjan算法QAQ

    tarjantql!

    • 深搜一遍求出时间戳
    • 定义一个追溯值(low_{x})(min{{i|i in { {a|a in subtree(x) || a in } }{a可通过一条不在搜索树上的边到达subtree(x)中的节点} }})
    • 那么珂以通过一遍dfs搜出dfn和low数组
    • 接下来讲讲如何判定是否是割点/边:

    割边判定:边(x,y)是割边当且仅当(dfn_{x} le low_{y})

    • 直接根据定义yy一下即可
    • 无向图需要处理一下重边个数问题:
    • 当fa为x的父亲的时候,如果有重边则珂以用来更新
    • 珂以用成对变换解决

    割点判定:

    • 对于不是搜索树根节点点x,若存在一x的子节点y使得(dfn_{x} leq low_{y}),则x是割点
    • 如x为根节点,则需要两个这样的y
    • 割点为(leq),不需考虑父节点与重边

    缩点

    • 定义:若一个无向图没有割点,则称其为点双联通图,同理我们称没有割边的图为边双联通图
    • 无向图的极大双联通子图被称为点双联通分量,边同理

    我trl跳过无向图tarjan缩点


    好吧我图论渣渣就是没办法,放了放了,先搞Dp和数据结构,以后再来填这个坑

    I'm BACK!

    JZOJ图论好题

    3936. 【GDOI2015模拟11.22】假期计划

    观察到k很小,珂以对所有k执行dijkstra求出最短路,时间复杂度O(KNlgN)

    对于一次询问(x,y),先暴力枚举一遍所有枢纽,设枚举到枢纽i,计算(x->i->y)的最短路,珂以O(1)求出

    时间复杂度O(KNlgN+QM),卡卡常就珂以通过此题

    /*
        Copyright(c) TYQ
        All rights served;
    */
    #include<iostream>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #define MAXN  20005
    #define MAXM  20005
    #define MAXK  205
    #define MAXQ  50005 
    using namespace std;
    int edge[MAXM],ver[MAXM],Next[MAXM],head[MAXN],temp[MAXK] ;
    int d[MAXK][MAXN];
    bool v[MAXQ],intemp[MAXN] ;
    int N,K,M,Query,tot,sum,num ;
    void add(int x,int y,int z){
    	edge[++tot]=z,ver[tot]=y,Next[tot]=head[x],head[x]=tot ;
    }
    priority_queue<pair<int,int> > q;
    void dijkstra(int start){
    	while(q.size())q.pop() ;
    	memset(v,0,sizeof(v)) ;
    	d[start][start]=0;
    	q.push(make_pair(d[start][start],start)) ;
    	while(q.size()){
    		int x = q.top().second ;
    		q.pop() ;
    		if(v[x])continue ;
    		v[x]=true ;
    		for(int i = head[x]; i;i = Next[i]){
    			int y = ver[i] , z = edge[i] ;
    			if(d[start][y] > d[start][x] + z){
    				d[start][y] = d[start][x] + z ;
    				q.push(make_pair(-d[start][y],y)) ;
    			}
    		}
    	}
    }
    int main(){
    	memset(d,0x3f,sizeof(d)); 
    	scanf("%d%d%d%d",& N,& M,& K,& Query) ;
    	for(int i=1;i<=M;++i){
    		int x,y,z;
    		scanf("%d%d%d",&x,&y,&z);
    		add(x,y,z) ;
    	}
    	for(int i=1;i<=K;++i){
    		scanf("%d",& temp[i]) ;
    		intemp[temp[i]] = true; 
    		dijkstra(temp[i]) ;
    		//for(int j=1;j<=N;++j)printf("%d ",d[temp[i]][j]) ;printf("
    ") ;
    	}
    	while(Query--){
    		int x,y;
    		scanf("%d%d",&x,&y) ;
    		int minv = 0x7f7f7f7f ;
    		for(int i=head[x]; i;i=Next[i]){
    			//printf("(%d,%d)
    ",i,ver[i]) ;
    			if(intemp[ver[i]])minv = min(minv,edge[i]+d[ver[i]][y]) ;
    		}
    		if(minv!=0x7f7f7f7f)sum+=minv,++num/*,printf("can
    ")*/ ;
    	}
    	printf("%d
    %d
    ",num,sum); 
    	return 0;
    }
    
    

    Warning!
    
    本文由 TYQ 创作,采用 知识共享署名 4.0 国际许可协议进行许可。
    转载要与作者联系,并需在正文明显处署名作者且注明文章出处。
    对了,我永远喜欢C++啊。
    
  • 相关阅读:
    ubuntu 16.04 更新后搜狗输入法无法输入中文的问题
    转: 苹果APNS的说明
    转:svn 更新指定文件夹
    转: Java 应用一般架构
    【原创】关于bug反正出现的问题可能
    App开发者博客之: 包建强 (专注移动app开发)
    转: 阿里跨平台移动开发工具Weex
    【原创】存储层设计的一些方法论
    转:车牌的自动截取与识别方案
    转: java web demo的示例
  • 原文地址:https://www.cnblogs.com/tyqtyq/p/9775331.html
Copyright © 2011-2022 走看看