zoukankan      html  css  js  c++  java
  • Silver Cow Party

    Silver Cow Party

    给出一个n个点m条边的有向图,(w[i][j])为i到j的边权,给出一个点X,询问从每个点出发到达X再回到起点的路径长度和最大值,(nleq 1000,mleq 100000)

    显然为单源最短路径的题目,考虑点为起点终点的取反,建反边,工具是bfs(边权为1),双端队列bfs(边权0,1),优先队列bfs(边权为正)。

    显然从点X出发得到到达每一个点i的路径长度即该点i返回时路径长度,记做(dis1[i]),那么建反边以后,从X到达的点i的路径长度记做(dis2[i])

    用优先队列bfs求出这两个数组后,取最大的(dis1[i]+dis2[i])即可。

    参考代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define il inline
    #define ri register
    #define Size 1050
    #define intmax 1061109567
    using namespace std;
    template<class free>
    struct heap{
    	free a[Size*Size];int n;
    	il void push(free x){
    		a[++n]=x;ri int p(n);
    		while(p>1)
    			if(a[p]<a[p>>1])
    				swap(a[p],a[p>>1]),
    					p>>=1;
    			else break;
    	}
    	il void pop(){
    		a[1]=a[n--];ri int p(1),s(2);
    		while(s<=n){
    			if(s<n&&a[s+1]<a[s])++s;
    			if(a[s]<a[p])
    				swap(a[s],a[p]),
    					p=s,s<<=1;
    			else break;
    		}
    	}
    };
    struct pi{
    	int x,y;
    	il bool operator<(const pi&a)const{
    		return y<a.y;
    	}
    };
    heap<pi>H;
    struct point{
    	point*next;int to,w;
    }*head[Size],*Head[Size];
    int dis1[Size],dis2[Size];
    il void read(int&),link(int,int,int,point**),
    					 dijistra(int,int*,point**);
    int main(){
    	int n,m,x;
    	read(n),read(m),read(x);
    	for(int i(1),u,v,w;i<=m;++i)
    		read(u),read(v),read(w),
    			link(u,v,w,head),
    			link(v,u,w,Head);
    	memset(dis1,-1,sizeof(dis1)),dijistra(x,dis1,head);
    	memset(dis2,-1,sizeof(dis2)),dijistra(x,dis2,Head);
    	int ans(-intmax);
    	for(int i(1);i<=n;++i)
    		ans=max(ans,dis1[i]+dis2[i]);
    	printf("%d",ans);
    	return 0;
    }
    il void dijistra(int s,int *dis,point**head){
    	H.n=0,H.push({s,0});pi sour;
    	while(H.n){
    		sour=H.a[1],H.pop();
    		if(dis[sour.x]>=0)continue;
    		dis[sour.x]=sour.y;
    		for(point*i(head[sour.x]);i!=NULL;i=i->next)
    			if(dis[i->to]<0)
    				H.push({i->to,i->w+sour.y});
    	}
    }
    il void link(int u,int v,int w,point**head){
    	head[u]=new point{head[u],v,w};
    }
    il void read(int &x){
    	x^=x;ri char c;while(c=getchar(),c<'0'||c>'9');
    	while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
    }
    
  • 相关阅读:
    407 Trapping Rain Water II 接雨水 II
    406 Queue Reconstruction by Height 根据身高重建队列
    405 Convert a Number to Hexadecimal 数字转换为十六进制数
    404 Sum of Left Leaves 左叶子之和
    403 Frog Jump 青蛙过河
    402 Remove K Digits 移掉K位数字
    401 Binary Watch 二进制手表
    400 Nth Digit 第N个数字
    398 Random Pick Index 随机数索引
    397 Integer Replacement 整数替换
  • 原文地址:https://www.cnblogs.com/a1b3c7d9/p/11408444.html
Copyright © 2011-2022 走看看