zoukankan      html  css  js  c++  java
  • 题解 POJ3613 【Cow Relays】

    题目链接:Link

    Problem

    Solution

    不难发现:Floyd的计算过程非常类似于矩阵乘法,尝试对其进行分治后不难证明可以套用矩阵快速幂的方法进行快速计算。

    Code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<map>
    #include<cassert>
    using namespace std;
    const int oo=0x3f3f3f3f;
    const int maxn=210;
    int P,n,m,s,e,a[maxn],b[maxn],c[maxn],d[maxn][maxn],res[maxn][maxn],tmp[maxn][maxn];
    map<int,int> hsh;
    inline void cal(int a[maxn][maxn],int b[maxn][maxn],int c[maxn][maxn])
    {
    	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
    	{
    		c[i][j]=oo;
    		for(int k=1;k<=n;k++) c[i][j]=min(c[i][j],a[i][k]+b[k][j]);
    	}
    }
    void ksm(int a[maxn][maxn],int b,int c[maxn][maxn])
    {
    	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) c[i][j]=oo;
    	for(int i=1;i<=n;i++) c[i][i]=0;
    	for(;b;b>>=1)
    	{
    		if(b&1) { cal(a,c,tmp); memcpy(c,tmp,4*maxn*maxn); }
    		cal(a,a,tmp);
    		memcpy(a,tmp,4*maxn*maxn);
    	}
    }
    int main()
    {
    	#ifdef local
    	freopen("pro.in","r",stdin);
    	#endif
    	scanf("%d%d%d%d",&P,&m,&s,&e);
    	for(int i=1;i<=m;i++) scanf("%d%d%d",&c[i],&a[i],&b[i]);
    	for(int i=1;i<=m;i++)
    	{
    		if(hsh[a[i]]==0) hsh[a[i]]=++n;
    		if(hsh[b[i]]==0) hsh[b[i]]=++n;
    	}
    	if(hsh[s]==0||hsh[e]==0) return 1;
    	memset(d,0x3f,sizeof(d));
    	// printf("n=%d s=%d e=%d
    ",n,hsh[s],hsh[e]);
    	for(int i=1;i<=m;i++)
    	{
    		d[hsh[a[i]]][hsh[b[i]]]=d[hsh[b[i]]][hsh[a[i]]]=c[i];
    		// printf("(%d,%d,%d)
    ",hsh[a[i]],hsh[b[i]],c[i]);
    	}
    	ksm(d,P,res);
    	printf("%d
    ",res[hsh[s]][hsh[e]]);
    	return 0;
    }
    
  • 相关阅读:
    常用命令
    经典算法
    框架
    计算机网络
    设计模式
    JVM
    数据库
    多线程
    Java中HashMap的底层实现原理
    构建大小顶堆
  • 原文地址:https://www.cnblogs.com/happyZYM/p/11656662.html
Copyright © 2011-2022 走看看