【POJ3613】【USACO 2007 Nov Gold】 2.Cow Relays 矩阵乘法?

题意:给你一个m条边的图,求s到t的正好用k条边的最短路。

(输入k,t,s,t)

题解:

先说说暴力。

动规f[k][i][j]表示i到j经过k条边的最短路,然后外层循环k一遍遍跑最后出解。

显然大概率T。

然后有一种思路:

我们可以动规求得f[k][i][j]表示i到j经过k条边的最短路,然后再求g[i]表示从终点走i步回到终点的最短路。

这样我们就可以乱搞过了。(没写,也没细想)

再之后是正解:

我们可以利用类似于快速幂的方法求f[i][j]表示i到j正好用多少多少步。

然后思想是使用边数的累加,或者叫倍增。

贴代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 205
#define M 1005
#define inf 0x3f3f3f3f
using namespace std;
int n,m,s,t;
int hash[M],dis[N][N],temp[N][N],f[N][N];
void power_floyd(int K)
{
	int i,j,k;
	while(K)
	{
		if(K&1)
		{
			memset(temp,0x3f,sizeof temp);
			for(k=1;k<=n;k++)for(i=1;i<=n;i++)for(j=1;j<=n;j++)temp[i][j]=min(temp[i][j],f[i][k]+dis[k][j]);
			for(i=1;i<=n;i++)for(j=1;j<=n;j++)f[i][j]=temp[i][j];
		}
		memset(temp,0x3f,sizeof temp);
		for(k=1;k<=n;k++)for(i=1;i<=n;i++)for(j=1;j<=n;j++)temp[i][j]=min(temp[i][j],dis[i][k]+dis[k][j]);
		for(i=1;i<=n;i++)for(j=1;j<=n;j++)dis[i][j]=temp[i][j];
		K>>=1;
	}
	return ;
}
int main()
{
//	freopen("test.in","r",stdin);
	int i,j,k;
	int a,b,c;
	memset(f,0x3f,sizeof f);
	memset(dis,0x3f,sizeof dis);
	for(i=1;i<=200;i++)f[i][i]=0;
	scanf("%d%d%d%d",&k,&m,&s,&t);
	while(m--)
	{
		scanf("%d%d%d",&c,&a,&b);
		if(!hash[a])hash[a]=++n;
		if(!hash[b])hash[b]=++n;
		dis[hash[a]][hash[b]]=dis[hash[b]][hash[a]]=c;
	}
	s=hash[s],t=hash[t];
	power_floyd(k);
	printf("%d\n",f[s][t]);
	return 0;
}
时间: 2024-08-24 16:03:10

【POJ3613】【USACO 2007 Nov Gold】 2.Cow Relays 矩阵乘法?的相关文章

【POJ3614】【USACO 2007 Nov Gold】 3.Sunscreen 贪心

题意: 有若干个区间,若干种数,每个数告诉你有多少个. 然后一个数可以被放到一个x∈该区间 的区间,问最多有多少个区间可以被放. 题解: 显然我们可以用二分图最大匹配做,水题. 但是此题有别的技巧. 就是我们可以贪心进行处理. 首先我们考虑到需要将两种数都排个序. 然后再进行贪心. 一种错误的贪心法是单调队列式贪心,就是记录个top,然后单调往后推. 这个不仔细想还不知道它是错的. 额,至于卡它的数据,,我可以提供给你一个错误代码和一个拍子,你们可以自己拍一组数据出来,很高效. 这里贴一份错误代

【POJ3612】【USACO 2007 Nov Gold 】1.Telephone Wire 动规

题意: 给出若干棵树的高度,你可以进行一种操作:把某棵树增高h,花费为h*h. 操作完成后连线,两棵树间花费为高度差*定值c. 求两种花费加和最小值. 题解: 跟NOIP2014 D1T3很像. 暴力动规是O(1*10^9)会T 所以单调队列一下,每颗树扫两遍结束. 完事,看水代码吧. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N

【POJ3612】【USACO 2007 Nov Gold】 1.Telephone Wire 动态调节

意甲冠军: 一些树高给出.行一种操作:把某棵树增高h,花费为h*h. 操作完毕后连线,两棵树间花费为高度差*定值c. 求两种花费加和最小值. 题解: 跟NOIP2014 D1T3非常像. 暴力动规是O(1*10^9)会T 所以单调队列一下,每颗树扫两遍结束. 完事,看水代码吧. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 101

【BZOJ】【1046】/【POJ】【3613】【USACO 2007 Nov】Cow Relays 奶牛接力跑

倍增+Floyd 题解:http://www.cnblogs.com/lmnx/archive/2012/05/03/2481217.html 神题啊= =Floyd真是博大精深…… 题目大意为求S到E,恰好经过N条边的最短路径(姑且称为路径吧,虽然好像已经不是了……) 总共只有大约200个点(很多点根本没走到,离散化一下即可)所以可以考虑Floyd算最短路. 引用下题解: 题目求i,j之间边数恰为N的最短路径(边可以重复走),我们知道线性代数中有:01邻接矩阵A的K次方C=A^K,C[i][j

奶牛接力 (Cow Relays, USACO 2007 Nov)

题目描述 For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a relay race using the T (2 ≤ T ≤ 100) cow trails throughout the pasture. Each trail connects two different intersections (1 ≤ I1i ≤ 1,000; 1 ≤ I2i ≤ 1,000), each

BZOJ 1706 usaco 2007 Nov relays 奶牛接力跑/POJ 3613 Cow Relays 倍增Floyd

题目大意:求恰好走k步从S到T的最短路. 思路:设f[p][i][j]为从i到j恰好走2^p步的最短路,DP方程十分简单:f[p][i][j] = min(f[p][i][j],f[p - 1][i][k] + f[p - 1][k][j]); 对总步数T进行二进制拆分,在T有1的位置上,假如这个位置为p,那么就用f[p][][]来更新答案g[][],最后得到的g[][]就是答案矩阵. 注意要离散化一下.. CODE: #include <cstdio> #include <cstrin

BZOJ 1641 USACO 2007 Nov. Cow Hurdles 奶牛跨栏

[题解] 弗洛伊德.更新距离的时候把$f[i][j]=min(f[i][j],f[i][k]+f[k][j])$改为$f[i][j]=min(f[i][j],max(f[i][k],f[k][j]))$. #include<cstdio> #include<algorithm> #include<cstring> #define N (400) #define rg register using namespace std; int n,m,t,a[N][N]; inl

【BZOJ1229】【USACO 2008 Nov Gold】 4.Toys sadstory 三分+贪心

sad story:我们自己oj的数据貌似有点问题.标程WA了5% 题解: 复制去Google翻译翻译结果 首先引一下VFK神犇的证明来证明一下这道题是三分.. { 我来告诉你世界的真相 = = 因为这题能最小费用最大流 每次最短路长度不降 所以是单峰的 最短路长度就是差分值.. 所以一阶导不降.. 是不是简单粗暴 你要证函数是单峰的. 当然是证斜率什么的 } 三分完初始买了多少个玩具,然后就是贪心. 首先我想说这个贪心真动规.虽然它真的是贪心. 首先先说一种错误的贪心. 就是从前往后扫,优先用

USACO 2007 NOV Sunscreen

题目 题目描述 To avoid unsightly burns while tanning, each of the C (1 ≤ C ≤ 2500) cows must cover her hide with sunscreen when they're at the beach. Cow i has a minimum and maximum SPF rating (1 ≤ minSPFi ≤ 1,000; minSPFi ≤ maxSPFi ≤ 1,000) that will work