码迷,mamicode.com
首页 > 其他好文 > 详细

图论板子

时间:2020-06-19 01:21:59      阅读:55      评论:0      收藏:0      [点我收藏+]

标签:dfs   struct   ==   str1   const   本职工作   tar   string   dag   

好多板子都没打啊...

最短路

dij

struct node
{
    int link;
    long long w;
    bool operator < (const node &qq) const{
        return qq.w<w;
    }
};
vector <node> f[N];
priority_queue <node> q;
void dij(int s)
{
    while(!q.empty())
        q.pop();
    for(int i=1;i<=n;i++)
        dis[i]=inf;
    dis[s]=0;
    q.push((node){s,0});
    while(!q.empty())
    {  
        node temp=q.top();
        q.pop();
        if(use[temp.link])
            continue;
        use[temp.link] = 1;
        for(auto i:f[temp.link])
        {
            if(dis[i.link]>=dis[temp.link]+i.w)
            {
                dis[i.link] = dis[temp.link] + i.w;
                q.push((node){i.link, dis[i.link]});
            }
        }

    }
}

spfa

void spfa(int s)
{
    memset(use,0,sizeof(use));
    memset(dis,0x7f,sizeof(dis));
    use[s]=1;
    dis[s]=0;
    q.push((node){s,0});
     while(!q.empty())
    {
        node temp=q.front();
        q.pop();
        use[temp.link]=0;
        for(int i=0;i<f[temp.link].size();i++)
        {
            node xx=f[temp.link][i];
            if(dis[xx.link]>dis[temp.link]+xx.w)
            {
                dis[xx.link]=dis[temp.link]+xx.w;
                if(!use[xx.link])
                {
                    q.push((node){xx.link,dis[xx.link]});
                    use[xx.link]=1;
                }
            }
        }
    }
}

spfa可以跑负权,但是dijstar不行,都可以跑最长路找环(除了跑有负权的边以外别用spfa了)

拓扑排序

void top()
{
    while(!q.empty())
    {  
        int temp=q.front();
        q.pop();
        for(auto i:f[temp])
        {
            d[i]--;
            /*code*/
            if(d[i]==0)
                q.push(i);
        }
    }
}

拓扑排序也可以找最短路|最长路(有人又花里胡哨把这叫dp)就在code里加dis[i]=min(...)就完事了

和dijkstar本质就是只能DAG里面找吧,并且只能从入度为0的点为起点,优点就是可以同时找多条起点和终点的dis(从这个答案角度来说,叫dp似乎也没问题)虽然dijkstar建超级起点和汇点也行比较拓扑本职工作也不是干这的,别要求太多了

在有向无环图中可以拓扑排序来找到一个拓扑序列,拓扑排序也可以找环

由于拓扑排序每次都是从入度为0的点开始,而环上的点的入度都不会为0,所以环上的点就不会参加排序,也就是说,经过拓扑排序后剩下的边和点构成的都是环(入读不为零的点)

倍增LCA


fa[N][30],deep[N]
vector <int> f[N];
void dfs(int x)
{
	for(int i=1;i<=25;i++)
	{
		if(deep[x]<(1<<i))
			break;
		fa[x][i]=fa[fa[x][i-1]][i-1];
	}
	for(int i=0;i<f[x].size();i++)
	{
		int temp=f[x][i];
		if(temp!=fa[x][0])
		{
			fa[temp][0]=x;
			deep[temp]=deep[x]+1;
			dfs(temp);
		}
	}
}
int lca(int x,int y)
{
	if(deep[x]<deep[y])
		swap(x,y);
	int t=deep[x]-deep[y];
	for(int i=0;i<=25;i++)
	{
		if(t&(1<<i))
			x=fa[x][i];
	}
	if(x==y)
		return x;
	for(int i=25;i>=0;i--)
	{
		if(fa[x][i]!=fa[y][i])
		{
			x=fa[x][i];
			y=fa[y][i];
		}
	}
	return fa[x][0];
}

并查集

也可以找环....tarjan也是用并查集来维护找出的强连通分量(能找环的太多了...)

int fa[N],ha[N],cnt;
long long w[N],sum[N];
int find(int x)
{
	//if(x==fa[x])
	//	return x;
	//return fa[x]=find(fa[x]);
    // 最后return 应该是return find(fa[x]) 不然有些题是过不了的(还是说本来就是错误的)
    return fa[x]==x?fa[x]:find(fa[x]);//等价该过的写法(我居然三年都没发现问题!!!)
}
void merge(int a,int b)
{
	int r1=find(ha[a]),r2=find(fa[ha[b]]);
	if(r1!=r2)
	{
		fa[r1]=r2;
		w[r2]+=w[r1];
		sum[r2]+=sum[r1];
	}
}
void move(int a,int b)
{
	// 把a移动到b集合 
	int r1=find(ha[a]),r2=find(ha[b]);
	if(r1!=r2)
	{
		w[r1]-=a;
		sum[r1]-=1;
		w[r2]+=a;
		sum[r2]+=1;
		ha[a]=++cnt; //先把a移出再定向father
		// 虽然之前的ha[a]还在集合里,但是之后再也不会用到,并且权值该减掉的全部减掉了所以相当于删除操作 
		fa[ha[a]]=r2;
	}
} 
int main()

强连通

缩点

void tarjan(int x)
{
	dfn[x]=low[x]=++tot;
	use[x]=1;
	s.push(x);
	for(int i=0;i<f[x].size();i++)
	{
		int temp=f[x][i];
		if(use[temp]==0)
		{
			tarjan(temp);
			low[x]=min(low[x],low[temp]);
		}
		else
		{
			if(use[temp]==1)
				low[x]=min(low[x],dfn[temp]);
		}
	}
	if(low[x]==dfn[x])//类似并查集合并
	{
		sum++;
		while(!s.empty())
		{
			int temp=s.top();
			s.pop();
			use[temp]=0;
			be[temp]=sum;//sum是最后缩点后的点个数
			sumv[sum]+=w[temp];//权值该干嘛干嘛
			if(x==temp)
				return ;
		}
	}
}

高精

搞烦了实在不行换python

似乎和图论没啥关系,加都加了算了

string add(string str1,string str2)
{
    string str;
    int len1=str1.length();
    int len2=str2.length();
    //前面补0,弄成长度相同
    if(len1<len2)
    {
        for(int i=1;i<=len2-len1;i++)
           str1="0"+str1;
    }
    else
    {
        for(int i=1;i<=len1-len2;i++)
           str2="0"+str2;
    }
    len1=str1.length();
    int cf=0;
    int temp;
    for(int i=len1-1;i>=0;i--)
    {
        temp=str1[i]-‘0‘+str2[i]-‘0‘+cf;
        cf=temp/10;
        temp%=10;
        str=char(temp+‘0‘)+str;
    }
    if(cf!=0)  str=char(cf+‘0‘)+str;
    return str;
}

图论板子

标签:dfs   struct   ==   str1   const   本职工作   tar   string   dag   

原文地址:https://www.cnblogs.com/cherrypill/p/13154656.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!