• BZOJ 1631 Usaco 2007 Feb. Cow Party


    【题解】

      最短路裸题。。

      本题要求出每个点到终点走最短路来回的距离,因此我们先跑一遍最短路得出每个点到终点的最短距离,然后把边反向再跑一遍最短路,两次结果之和即是答案。

      

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define N (2010)
    #define M (200010)
    #define rg register
    #define fa (x>>1)
    using namespace std;
    int n,m,x,tot,ans,dis[N],last[N],pos[N],sum[N];
    struct edge{
    	int to,pre,dis;
    }e[M];
    struct heap{
    	int to,dis;
    }h[N];
    struct record{
    	int u,v,dis;
    }rec[M];
    inline int read(){
    	int k=0,f=1; char c=getchar();
    	while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    	while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
    	return k*f;
    }
    inline void add(int x,int y,int z){e[++tot]=(edge){y,last[x],z}; last[x]=tot;}
    inline void up(int x){
    	while(x>1&&h[fa].dis>h[x].dis){
    		swap(h[fa],h[x]); swap(pos[h[fa].to],pos[h[x].to]);
    		x=fa;
    	}
    }
    inline void down(int x){
    	while(x<=(tot>>1)){
    		int son=x<<1;
    		if(son<tot&&h[son].dis>h[son+1].dis) son++;
    		if(h[son].dis<h[x].dis){
    			swap(h[son],h[x]); swap(pos[h[son].to],pos[h[x].to]);
    			x=son;
    		}
    		else return;
    	}
    }
    void dijkstra(int x){
    	h[pos[x]=tot=1]=(heap){x,dis[x]=0};
    	while(tot){
    		int now=h[1].to; h[1]=h[tot--]; if(tot) down(1);
    		for(int i=last[now],to;i;i=e[i].pre)
    		if(dis[to=e[i].to]>dis[now]+e[i].dis){
    			dis[to]=dis[now]+e[i].dis;
    			if(!pos[to]) h[pos[to]=++tot]=(heap){to,dis[to]};
    			up(pos[to]);
    		}
    		pos[now]=0;
    	}
    }
    inline void clear(){
    	memset(last,0,sizeof(last));
    	memset(dis,32,sizeof(dis));
    	memset(pos,0,sizeof(pos));
    	tot=0;
    }
    void out(){
    	for(int i=1;i<=n;i++) printf("%d ",dis[i]); puts("");
    }
    int main(){
    	n=read(); m=read(); x=read();
    	clear();
    	for(rg int i=1;i<=m;i++){
    		rec[i].u=read(); rec[i].v=read();
    		add(rec[i].u,rec[i].v,rec[i].dis=read());
    	}
    	dijkstra(x); //out();
    	for(int i=1;i<=n;i++) sum[i]=dis[i];
    	clear();
    	for(rg int i=1;i<=m;i++) add(rec[i].v,rec[i].u,rec[i].dis);
    	dijkstra(x); //out();
    	for(int i=1;i<=n;i++) ans=max(ans,sum[i]+dis[i]);
    	printf("%d
    ",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    测试可以自动化,日常工作也可以自动化,autoit帮你搞定!
    工作了几年的IT人想要创业,必看的失败经验
    使用autoit,可以节省您很多时间
    美容院会籍管理,看着简单,其实很复杂
    简历,求职求项目,硕士4年工作经验2年管理经验
    maven+svn+hudson+weblogic构建持续集成环境
    快速开发框架V0.001(免费、100%开源)
    进销存管理系统的设计与实现
    窗体的位置startposition manual
    破解网页文章无法复制方法全集合
  • 原文地址:https://www.cnblogs.com/DriverLao/p/8404276.html
Copyright © 2020-2023  润新知