zoukankan      html  css  js  c++  java
  • 模板—线段树优化建图

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #define MAXN 2500010
    using namespace std;
    struct edge
    {
    	int u,v,w,nxt;
    	#define u(x) ed[x].u
    	#define v(x) ed[x].v
    	#define w(x) ed[x].w
    	#define n(x) ed[x].nxt
    }ed[MAXN<<3];
    int first[MAXN],num_e;
    #define f(x) first[x]
    int n,m,p;
    inline void add_e(int u,int v,int w);
    struct tree
    {
    	int l,r,ls,rs;
    	#define l(x)  tr[x].l
    	#define r(x)  tr[x].r
    	#define ls(x) tr[x].ls
    	#define rs(x) tr[x].rs
    }tr[MAXN];
    int ra,rb,pos[MAXN],tot;
    void build(int &k,int ll,int rr,int opt)
    {
    	k=++tot;
    	l(k)=ll,r(k)=rr;
    	if(ll==rr){if(opt)pos[ll]=k;return;}
    	int mid=(ll+rr)>>1;
    	build(ls(k),ll,mid,opt);
    	build(rs(k),mid+1,rr,opt);
    	if(opt)add_e(ls(k),k,0),add_e(rs(k),k,0);
    	else   add_e(k,ls(k),0),add_e(k,rs(k),0);
    }
    void addleaf(int k)
    {
    	if(l(k)==r(k)){add_e(k,pos[l(k)],0);return;}
    	addleaf(ls(k)),addleaf(rs(k));
    }
    void treeadd(int k,int ll,int rr,int to,int opt)
    {
    	if(ll<=l(k) && rr>=r(k)){opt?add_e(k,to,0):add_e(to,k,0);return;}
    	int mid=(l(k)+r(k))>>1;
    	if(ll<=mid)treeadd(ls(k),ll,rr,to,opt);
    	if(rr> mid)treeadd(rs(k),ll,rr,to,opt);
    }
    void add(int a,int b,int c,int d)
    {
    	int p1=++tot,p2=++tot;
    	treeadd(ra,a,b,p1,1);
    	add_e(p1,p2,1);
    	treeadd(rb,c,d,p2,0);
    }
    int dis[MAXN];bool v[MAXN];
    void dist(int s)
    {
    	memset(dis,0x7f,sizeof(dis));
    	priority_queue<pair<int,int> >q;
    	dis[s]=0;q.push(make_pair(0,s));
    	while(q.size())
    	{
    		int x=q.top().second;q.pop();
    		if(v[x])continue;v[x]=1;
    
    		for(int i=f(x);i;i=n(i))
    		if(!v[v(i)] && dis[v(i)]>dis[x]+w(i))
    			dis[v(i)]=dis[x]+w(i),
    			q.push(make_pair(-dis[v(i)],v(i)));
    	}
    }
    signed main()
    {
    //	freopen("in.txt","r",stdin);
    
    	scanf("%d%d%d",&n,&m,&p);
    	build(ra,1,n,1),build(rb,1,n,0);addleaf(rb);
    	for(int i=1;i<=m;i++)
    	{
    		int a,b,c,d;
    		scanf("%d%d%d%d",&a,&b,&c,&d);
    		add(a,b,c,d),add(c,d,a,b);
    	}
    	dist(pos[p]);
    	for(int i=1;i<=n;i++)
    	printf("%d
    ",dis[pos[i]]);
    }
    inline void add_e(int u,int v,int w)
    {
    	++num_e;
    	u(num_e)=u;
    	v(num_e)=v;
    	w(num_e)=w;
    	n(num_e)=f(u);
    	f(u)=num_e;
    }
    
  • 相关阅读:
    29.内置方法中之描述符
    28. 面向对象进阶之内置方法上
    Sort Colors*
    Implement Trie (Prefix Tree)
    Course Schedule
    Permutations
    Reverse Linked List
    Decode Ways
    Subsets *
    Longest Consecutive Sequence *
  • 原文地址:https://www.cnblogs.com/Al-Ca/p/11182978.html
Copyright © 2011-2022 走看看