题目链接: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步最短路
#include<stdio.h>
#include<string.h>
#define INF 0x3f3f3f3f
#define N 101
struct Matrix
{
int edge[N][N];
}map,tmp,res;
int n,f[N*10];
Matrix mul(Matrix x,Matrix y) //floyd
{
memset(tmp.edge,INF,sizeof(tmp.edge));
int i,j,k;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
for(k=1;k<=n;k++)
if(tmp.edge[i][j]>x.edge[i][k]+y.edge[k][j])
tmp.edge[i][j]=x.edge[i][k]+y.edge[k][j];
return tmp;
}
void quickpow(int k)
{
int i;
memset(res.edge,INF,sizeof(res.edge));
for(i=1;i<=n;i++)
res.edge[i][i]=0;
while(k) //二进制思想
{
if(k&1)
res=mul(res,map);
map=mul(map,map);
k>>=1;
}
}
int main()
{
int i,k,t,s,e,len,u,v;
scanf("%d%d%d%d",&k,&t,&s,&e);
memset(map.edge,INF,sizeof(map.edge));
memset(f,-1,sizeof(f));
int num=0;
for(i=0;i<t;i++)
{
scanf("%d%d%d",&len,&u,&v);
if(f[u]==-1) //离散化
f[u]=++num;
if(f[v]==-1) //离散化
f[v]=++num;
map.edge[f[u]][f[v]]=map.edge[f[v]][f[u]]=len;
}
n=num;
quickpow(k);
printf("%d\n",res.edge[f[s]][f[e]]);
return 0;
}
矩阵十题【十】 poj 3613 Cow Relays,布布扣,bubuko.com
原文地址:http://blog.csdn.net/u010468553/article/details/38494869