zoukankan      html  css  js  c++  java
  • 【洛谷P2966】Cow Toll Paths

    题目大意:给定 N 个节点,M 条边的无向图,边有边权,点有点权,现给出 Q 个询问,每个询问查询两个节点之间的最短路径,这里最短路径的定义是两个节点之间的最短路径与这条路径中经过的节点点权的最大值之和。

    题解:多源最短路问题应该用 floyd 算法来处理,由于最短路径涉及到路径中最大的点权,因此如何在决策阶段快速进行状态转移是这道题考虑的核心。若每次进行枚举点权,复杂度显然爆炸。因此在开始时对点权进行排序,这样对于带点权的最短路径的决策仅由 i,j,k 三个点点权的最大值决定,时间复杂度为 (O(n^3))
    另:单纯计算多源最短路时,各个节点之间的顺序对答案无影响。(显然)

    代码如下

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pb push_back
    #define mp make_pair
    #define all(x) x.begin(),x.end()
    #define cls(a,b) memset(a,b,sizeof(a))
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> P;
    const int dx[]={0,1,0,-1};
    const int dy[]={1,0,-1,0};
    const int mod=1e9+7;
    const int inf=0x3f3f3f3f;
    const int maxn=251;
    const double eps=1e-6;
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline ll sqr(ll x){return x*x;}
    inline ll read(){
    	ll x=0,f=1;char ch;
    	do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
    	do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
    	return f*x;
    }
    /*--------------------------------------------------------*/
    
    int n,m,q;
    int f[maxn][maxn],g[maxn][maxn],mpp[maxn];
    struct node{int id,val;}ver[maxn];
    bool cmp(const node &a,const node &b){return a.val<b.val;}
    
    void read_and_parse(){
    	cls(f,0x3f),cls(g,0x3f);
    	for(int i=1;i<=n;i++)f[i][i];
    	n=read(),m=read(),q=read();
    	for(int i=1;i<=n;i++)ver[i].id=i,ver[i].val=read();
    	sort(ver+1,ver+n+1,cmp);
    	for(int i=1;i<=n;i++)mpp[ver[i].id]=i;
    	for(int i=1;i<=m;i++){
    		int x=read(),y=read(),z=read();
    		f[mpp[x]][mpp[y]]=f[mpp[y]][mpp[x]]=min(z,f[mpp[y]][mpp[x]]);
    	}
    }
    
    void floyd(){
    	for(int k=1;k<=n;k++)
    		for(int i=1;i<=n;i++)
    			for(int j=1;j<=n;j++){
    				f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
    				g[i][j]=min(g[i][j],f[i][j]+max(max(ver[i].val,ver[j].val),ver[k].val));
    			}
    }
    
    void solve(){
    	floyd();
    	while(q--){
    		int s=mpp[read()],t=mpp[read()];
    		printf("%d
    ",g[s][t]);
    	}
    }
    
    int main(){
    	read_and_parse();
    	solve();
    	return 0;
    }
    
    
  • 相关阅读:
    win32/mfc/qt 异常处理与总结
    tornado使用长连接并运行在nginx反向代理后面
    tornado中计算etag的一个BUG
    关于HTTP长连接的保持和断开
    系统时间不对导致cookie设置不成功
    tornado中模板的变量命令冲突
    unix时间戳转换
    Twisted echo server
    tornado长连接断开的处理机制
    rp_filter及Linux下多网卡接收多播的问题
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10656194.html
Copyright © 2011-2022 走看看