zoukankan      html  css  js  c++  java
  • [Usaco2009 Jan]安全路经Travel BZOJ1576 Dijkstra+树链剖分+线段树

    分析:

    Dijkstra求最短路树,在最短路树上进行操作,详情可见上一篇博客:http://www.cnblogs.com/Winniechen/p/9042937.html

    我觉得这个东西不压行写出了有点丑...之后写了一个压行后更丑的...

    附上压行后的代码:

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <queue>
    using namespace std;
    #define N 200005
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define inf 0x3f3f3f3f
    struct node
    {
    	int to,next,val;
    }E[N<<2],e[N<<1];
    int head[N],head1[N],cnt,cnt1,fa[N],a[N];
    int dep[N],anc[N],siz[N],son[N],idx[N],b[N];
    int dis[N],minn[N<<2],cov[N<<2],n,vis[N],c[N];
    void add1(int x,int y,int z){E[cnt1].to=y;E[cnt1].next=head1[x];E[cnt1].val=z;head1[x]=cnt1++;}
    void add(int x,int y,int z){e[cnt].to=y;e[cnt].next=head[x];e[cnt].val=z;head[x]=cnt++;}
    void Dijkstra()
    {
    	memset(dis,0x3f,sizeof(dis));int num=0;
    	priority_queue<pair<int ,int > >q;dis[1]=0;q.push(make_pair(0,1));
    	while(!q.empty())
    	{
    		if(num==n)break;
    		int x=q.top().second;q.pop();
    		if(vis[x])continue;vis[x]=1;num++;
    		for(int i=head1[x];i!=-1;i=E[i].next)
    		{
    			int to1=E[i].to;
    			if(dis[to1]+E[i].val==dis[x])add(to1,x,E[i].val),add(x,to1,E[i].val);
    		}
    		for(int i=head1[x];i!=-1;i=E[i].next)
    		{
    			int to1=E[i].to;
    			if(dis[x]+E[i].val<dis[to1])
    			{
    				dis[to1]=dis[x]+E[i].val;
    				q.push(make_pair(-dis[to1],to1));
    			}
    		}
    	}
    }
    void dfs1(int x,int from)
    {
    	fa[x]=from,dep[x]=dep[from]+1,siz[x]=1;
    	for(int i=head[x];i!=-1;i=e[i].next)
    	{
    		int to1=e[i].to;
    		if(to1!=from)
    		{
    			dfs1(to1,x);siz[x]+=siz[to1];
    			if(siz[son[x]]<siz[to1])son[x]=to1;
    		}
    	}
    }
    int tims;
    void dfs2(int x,int top)
    {
    	anc[x]=top;idx[x]=++tims;
    	if(son[x])dfs2(son[x],top);
    	for(int i=head[x];i!=-1;i=e[i].next)
    	{
    		int to1=e[i].to;
    		if(to1!=fa[x]&&to1!=son[x])dfs2(to1,to1);
    	}
    }
    void PushDown(int rt)
    {
    	if(cov[rt]!=inf)
    	{
    		int t=cov[rt];
    		cov[rt<<1]=min(cov[rt<<1],t);
    		minn[rt<<1]=min(minn[rt<<1],t);
    		cov[rt<<1|1]=min(cov[rt<<1|1],t);
    		minn[rt<<1|1]=min(minn[rt<<1|1],t);
    		cov[rt]=inf;
    	}
    }
    void build(int l,int r,int rt)
    {
    	minn[rt]=cov[rt]=inf;
    	if(l==r)return ;int m=(l+r)>>1;
    	build(lson);build(rson);
    }
    void Update(int L,int R,int c,int l,int r,int rt)
    {
    	if(L<=l&&r<=R)
    	{
    		minn[rt]=min(minn[rt],c);cov[rt]=min(cov[rt],c);
    		return ;
    	}
    	PushDown(rt);int m=(l+r)>>1;
    	if(L<=m)Update(L,R,c,lson);
    	if(m<R)Update(L,R,c,rson);
    }
    int query(int x,int l,int r,int rt)
    {
    	if(l==r)return minn[rt];
    	PushDown(rt);int m=(l+r)>>1;
    	if(m>=x)return query(x,lson);
    	else return query(x,rson);
    }
    void get_lca(int x,int y,int c)
    {
    	while(anc[x]!=anc[y])
    	{
    		if(dep[anc[x]]<dep[anc[y]])swap(x,y);
    		Update(idx[anc[x]],idx[x],c,1,n,1);x=fa[anc[x]];
    	}
    	if(dep[x]>dep[y])swap(x,y);
    	if(x!=y)Update(idx[x]+1,idx[y],c,1,n,1);
    }
    int main()
    {
    	int m;memset(head,-1,sizeof(head));memset(head1,-1,sizeof(head1));scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++)
    	{
    		int x,y,z;scanf("%d%d%d",&x,&y,&z);
    		add1(x,y,z);add1(y,x,z);a[i]=x,b[i]=y,c[i]=z;
    	}
    	Dijkstra();dfs1(1,0);dfs2(1,1);build(1,n,1);
    	for(int i=1;i<=m;i++)
    	{
    		if(abs(dis[a[i]]-dis[b[i]])==c[i])continue;
    		get_lca(a[i],b[i],dis[a[i]]+dis[b[i]]+c[i]);
    	}
    	for(int i=2;i<=n;i++)
    	{
    		int t=query(idx[i],1,n,1);
    		t==inf?printf("-1
    "):printf("%d
    ",t-dis[i]);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    LINUX超级用户(权限)在系统管理中的作用
    LINUX对超级用户和普通用户的理解
    LINUX设置SUID,SGID,Stick bit
    LINUX文件权限
    LINUX文件类型
    LINUX查询用户命令
    LINUX用户身份切换
    ACL权限设置
    Linux用户密码策略
    linux库列表
  • 原文地址:https://www.cnblogs.com/Winniechen/p/9042949.html
Copyright © 2011-2022 走看看