zoukankan      html  css  js  c++  java
  • bzoj 1706: [usaco2007 Nov]relays 奶牛接力跑【矩阵乘法+Floyd】

    唔不知道怎么说……大概核心是把矩阵快速幂的乘法部分变成了Floyd一样的东西,非常之神
    首先把点离散一下,最多有200个,然后建立邻接矩阵,a[u][v]为(u,v)之间的距离,没路就是inf
    然后注意重载乘号的部分,注意到这样乘一次就相当于把本来存了经过k条路的最短路的邻接矩阵变成存了经过k+1条路的最短路的邻接矩阵
    这样看来乘n次就行了,这里用矩阵快速幂
    妙啊

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int N=1005;
    const long long inf=1e15;
    int n,m,s,t,id[N],tot;
    struct qwe
    {
    	long long a[205][205];
    	qwe operator * (const qwe &b) const
    	{
    		qwe c;
    		for(int i=1;i<=tot;i++)
    			for(int j=1;j<=tot;j++)
    				c.a[i][j]=inf;
    		for(int k=1;k<=tot;k++)	
    			for(int i=1;i<=tot;i++)
    				for(int j=1;j<=tot;j++)
    					c.a[i][j]=min(c.a[i][j],a[i][k]+b.a[k][j]);
    		return c;
    	}
    }a,r;
    int read()
    {
    	int r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    int main()
    {
    	n=read(),m=read(),s=read(),t=read();
    	for(int i=1;i<=m;i++)
    	{
    		int z=read(),x=read(),y=read();
    		x=(id[x]!=0)?id[x]:(id[x]=++tot);
    		y=(id[y]!=0)?id[y]:(id[y]=++tot);//cerr<<x<<" "<<y<<endl;
    		a.a[x][y]=a.a[y][x]=z;
    	}
    	for(int i=1;i<=tot;i++)
    		for(int j=1;j<=tot;j++)
    			if(!a.a[i][j])
    				a.a[i][j]=inf;
    	int x=n-1;
    	r=a;
    	while(x)
    	{
    		if(x&1)
    			r=r*a;
    		a=a*a;
    		x>>=1;
    	}
    	printf("%lld
    ",r.a[id[s]][id[t]]);
    	return 0;
    }
    
  • 相关阅读:
    Live Writer配置
    protobufnet 学习手记
    好的Sql语句也能提高效率(二)
    关于CodeSmith的输出问题
    [Scrum]12.29
    [scrum] 1.4
    分享 关于c#注释的规范
    [Scrum] 1.3
    分享:将XML(VS提取注释时生成)转换为Chm的一个方法
    【Scrum】2010.12.27
  • 原文地址:https://www.cnblogs.com/lokiii/p/8997813.html
Copyright © 2011-2022 走看看