POJ 3613

可以利用DP的思想来做,不过是在DP时加上了矩阵乘法的思想而已,但乘法不是真的乘法,而是mp[a][i]+mp[i][b]<mp[a][b]则更新,其实更像FLOYD。

但这是符合乘法的格式的。

我们可以利用快速幂的做法来降低复杂度,同时把那些点离散化一下,因为T才100,最多是200多个点而已。

仅有此还不够,我觉得这道题更重要的是一个初始化的问题。

这题的数据可能有回到原点的数据,那么,若I->I=0的话,则会一直不动,所以要初始化到I->I=INF;

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;
const int inf=0x3f3f3f3f;
const int Maxn=220;
int mark[1010];

struct Matrax {
	int m[Maxn][Maxn];
};
Matrax a;
int counted=0;
Matrax multi(Matrax a,Matrax b){
	Matrax c;
	for(int i=0;i<counted;i++){
		for(int j=0;j<counted;j++){
			c.m[i][j]=inf;
			for(int k=0;k<counted;k++)
			c.m[i][j]=min(c.m[i][j],a.m[i][k]+b.m[k][j]);
		}
	}
	return c;
}

Matrax Powerg(int k){
	bool flag=false;
	Matrax ans,p=a;
	while(k){
		if(k&1){
			if(!flag){
				ans=p;
				flag=true;
			}
			else {
				ans=multi(ans,p);
			}
		}
		k>>=1;
		p=multi(p,p);
	}
	return ans;
}

int main(){
	int n,t,s,e,l,u,v,uu,vv;
	while(scanf("%d%d%d%d",&n,&t,&s,&e)!=EOF){
		counted=0;
		memset(mark,-1,sizeof(mark));
		for(int i=0;i<Maxn;i++){
			for(int j=0;j<Maxn;j++){
				a.m[i][j]=inf;
			}
		}
		for(int i=0;i<t;i++){
			scanf("%d%d%d",&l,&uu,&vv);
			if(mark[uu]==-1)
			mark[uu]=counted++;
			if(mark[vv]==-1)
			mark[vv]=counted++;
			u=mark[uu]; v=mark[vv];
			a.m[u][v]=a.m[v][u]=l;
		}
		Matrax ans=Powerg(n);
		s=mark[s]; e=mark[e];
		printf("%d\n",ans.m[s][e]);
	}
	return 0;
}

  

时间: 2024-11-06 03:34:22

POJ 3613的相关文章

POJ 3613 Cow Relays 恰好n步的最短路径

http://poj.org/problem?id=3613 题目大意: 有T条路,从s到e走n步,求最短路径. 思路: 看了别人的... 先看一下Floyd的核心思想: edge[i][j]=min(edge[i][j],edge[i][k]+edge[k][j]) i到j的最短路是i到j的直接路径或者经过k点的间接路径,但是矩阵的更新总是受到上一次更新的影响 如果每次的更新都存进新矩阵,那么edge[i][k]+edge[k][j]是不是表示只经过三个点两条边的路径呢? min(edge[i

矩阵十题【十】 poj 3613 Cow Relays

题目链接:http://poj.org/problem?id=3613 题目大意: 输入N,T,S,E,N表示要走的边数,T表示一共有几条边,S表示开始的点,E表示结束的点 给出一张无向连通图,求S到E经过N条边的最短路. N (2 ≤ N ≤ 1,000,000) T (2 ≤ T ≤ 100) (1 ≤ I1i ≤ 1,000; 1 ≤ I2i ≤ 1,000) 1 ≤ lengthi  ≤ 1,000 题目主要的思想就是用矩阵的乘法模拟出Floyd进行运算,是个很好的题目. //k步最短路

POJ 3613 Cow Relays (floyd + 矩阵快速幂)

题目大意: 求刚好经过K条路的最短路 我们知道如果一个矩阵A[i][j] 表示表示 i-j 是否可达 那么 A*A=B  B[i][j]  就表示   i-j 刚好走过两条路的方法数 那么同理 我们把i-j 的路径长度存到A 中. 在A*A的过程中,不断取小的,那么最后得到的也就是i - j 走过两条路的最短路了. 当然也是利用到了floyd的思想. 然后要求出K次的最短路,那么就是矩阵快速幂的工作了. 注意要离散化.用map #include <cstdio> #include <io

POJ 3613 Cow Relays (Floyd + 矩阵快速幂 + 离散化 神题!)

Cow Relays Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5611   Accepted: 2209 Description 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

poj 3613 经过k条边最短路 floyd+矩阵快速幂

http://poj.org/problem?id=3613 s->t上经过k条边的最短路 先把1000范围的点离散化到200中,然后使用最短路可以使用floyd,由于求的是经过k条路的最短路,跑k-1次"floyd"即可(使用矩阵快速幂的思想). 把给定的图转为邻接矩阵,即A(i,j)=1当且仅当存在一条边i->j.令C=A*A,那么C(i,j)=ΣA(i,k)*A(k,j),实际上就等于从点i到点j恰好经过2条边的路径数(枚举k为中转点).类似地,C*A的第i行第j列就

poj 3613 Cow Relays

Cow Relays Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5411   Accepted: 2153 Description 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

(floyd 倍增) poj 3613

Cow Relays Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5720   Accepted: 2266 Description 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

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

(floyd倍增) poj 3613

Cow Relays Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5651   Accepted: 2230 Description 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