• (不知道该起什么题目)


    老刘说让我写个图论的总结(一个月前),当时因为在写dp所以推了,今日看尧神在写,不妨补上;

    一些模板;

    //图论的一些模板;
    总结于 2017 3 28,尧神搞完了图论,我跟着写一波总结
     
     
     /*一个概念;欧拉路
     欧拉路也就是一笔画成问题,欧拉路的必要判定条件是每个点的入度为偶数,或者是只有两个点是奇数,
    当满足条件2时,这两个点必定一个是起点一个是终点;
    /*/
    最短路的求法
    {
    	1.
    	//floyed;
    	for(int i=1;i<=k;i++)
    		for(int j=1;j<=k;j++)
    			for(int u=1;u<=k;u++)
    			{
    				dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][u]);
    			}
    	//(500数据量的求法,基本没用;)
    	
    	//堆优化的dijkstra
    	#include<iostream>
    	#include<string>
    	#include<algorithm>
    	#include<queue>
    	typedef pair <int,int> pii;
    	viod dijkstra(int s){
    		priority_queue<pii>q;
    		memset(dis,10,sizeof(dis));
    		meset(vis,0,sizeof(vis));
    		d[s]=0;
    		q.push(make_pair(0,s));
    		while(!q.empty){
    			pii tmp=q.top();
    			q.pop();
    			int x=tmp.second;
    			if(vis[x])continue;
    			vis[x]=1;
    			for(int i=lin[x];i;i=e[i].next){
    				if(dis[e[i].y]>dis[x]+e[i].v){
    					dis[e[i].y]=dis[x]+e[i].v;
    					q.push(make_pair(e[i].y,x));
    				}
    			}
    		}
    	}
    	//判断是否有负环;
    	//bellman-ford;
    	//边表存贮;
    	int  bellman-ford(int st){
    		memset(dis,10,sizeof(dis);
    		dis[st]=0;
    		int num=0;
    		for(int i=1;i<=n;i++){
    			for(int i=1;i<=sum;i++){
    				if(dis[a[i].x]+a[i].v<dis[a[i].y])
    					dis[a[i].y]=dis[a[i].x]+a[i].v,num=1;
    				if(num==0)return 0;//无负环;
    			}
    			return 1;//有负环
    		}
    	}
    	//spfa;
    	void spfa(int st)
    	{
    		memset(dis,10,sizeof(dis));
    		memset(vis,0,sizeof(vis));
    		int head=0,tail=1;
    		while(head<tail)
    		{
    			head++;
    			int x=q[head];
    			vis[x]=0;
    			for(int i=lin[q[head]];i;i=e[i].next)
    			{
    				int y=e[i].y;
    				if(dis[x]+e[i].v<dis[y])
    				{
    					dis[y]=e[i].v+dis[x];
    					if(vis[y]==0)
    					{
    						vis[y]=1;
    						q[++tail]=y;
    						vis[y]=0;
    					}
    				}
    			}
    		}		
    	}
    	//最小生成树_边表
    	//kruskal
    	int getfather(int k)
    	{
    		if(k==father[k])return father[k];
    		father[k]=getfather(father[k]);
    		return father[k];
    	}	
    	void merge(int x,int y);
    	{
    		x=getfather(x);
    		y=getfather(y);
    		fahter[x]=father[y];	
    	}
    	int judge(int x,int y)//判断;
    	{
    		father[x]=getfather(x);
    		father[y]=getfather(y);
    		if(father[x]==father[y])return 1;
    		return 0;
    	}
    	int krskal(int x)
    	{
    		for(int i=1;i<=len;i++)
    		{
    			int x=e[i].x;
    			int y=e[i].y;
    			if(x!=y)
    			{
    				merge(x,y);
    			}
    		}
    	}	
    	
    	//topsort 据说是为了确定搜索顺序
    	void topsort()
    	{
    		for(int i=1;i<=n;i++)
    		{
    			if(vis[i]==0)
    				q[++tail]=i;
    		}
    		while(head<tail)
    		{
    			head++;
    			int x=q[head];
    			for(int i=lin[x];i;i=e[i].next)
    			{
    				int y=[i].y;
    				vis[y]--;
    				if(vis[y]==0)q[++tail]=y;
    			}
    		}
    	}//q 里存的即是topsort序列;
    
    
    //注意, topsort的序列并不是唯一的,枚举所有的排序情况需要用dfs来存;	
    
    //	割边割点与强连通分量;
    /* int dfn[10000000],low[10000000];
    	
    	割点;  所谓割点,即去掉此点后图不连通,那么只需求一下某个点是否能回到比他早的路即可;
    	
    	*/
    	trajan(int x,int father)
    	{
    		dfn[x]=low[x]=++num;
    		int son=0;
    		for(int i=lin[x];i;i=e[i].next)
    		{
    			int y=e[i].y;
    			if(y!=father)
    			{
    				if(!dfn[y])
    				{
    					trajan(y,x);
    					if(low[y]<low[x]);
    					low[x]=low[y],son++;
    				}
    				if(dfn[y]<low[x])low[x]=dfn[y],son++;
    			}
    		}
    		if(son==1&&father!=-1||son>=2)
    			f[x]=1;
    	}
    
    //	割边;去掉该边后图不连通;
    	trajan(int x,int fatherlen)
    	{
    		dfn[x]=low[x]=++num;
    		for(int i=lin[x];i;i=e[i].next)
    		{
    			int y=e[i].y;
    			if(i!=fatherlen)
    			{
    				if(!dfn[y])
    				{
    					trajan(y,x);
    					if(low[y]<low[x]);
    					low[x]=low[y];
    				}
    				if(dfn[y]<low[x])low[x]=dfn[y];
    			}
    		}
    		if(dfn[x]==low[x])f[fatherlen]=;
    	}
    	
    	//强连通分量;
    	//int tot=0;
    	//int tnt[10000000];
    	//int struck[1000000];
    	//int top=0;
    	//int bel[10000000];
    	trajan(int x,int father)
    	{
    		dfn[x]=low[x]=++num;
    		struck[++]
    		int son=0;
    		for(int i=lin[x];i;i=e[i].next)
    		{
    			int y=e[i].y;
    			if(!dfn[y])
    			{
    				trajan(y,x);
    				if(low[y]<low[x]);
    				low[x]=low[y];
    			}				
    			if(dfn[y]<low[x])low[x]=dfn[y];
    		}
    		if(dfn[x]==low[x])
    		{
    			tot++;int k;
    			while(k!=x)
    			{
    				k=struck[top--];
    				tnt[tot]++;
    				bel[k]=tot;
    			}
    		}
    	}
    	
    	
    	
    ///*/*/*/*/*/*/*/*/*/*/*/*/*终于写完了(累.....)*/*/*/*/*/*/*/*/*/*/*/*/*/*/*
    //*/*/*/*/*/*/*/*/*/*/*/*/*/*好像还有个什么差分约束,过两天再弄吧*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
    	
    	
    	
    }	
    

      

  • 相关阅读:
    [SDOI2009]生日礼物(单调队列)
    [luogu1638]逛画展(单调队列)
    【最短路】·SPFA算法实现
    [UVA10474]大理石在哪儿
    【转载】C++中string erase函数的使用
    【转载】高精度减法的OP写法
    【转载】ST表
    串门赛: NOIP2016模拟赛——By Marvolo 丢脸记
    Bzoj 3813 奇数国 题解 数论+线段树+状压
    Bzoj 2064 分裂 题解
  • 原文地址:https://www.cnblogs.com/Lazers/p/6639251.html
Copyright © 2020-2023  润新知