P2886 [USACO07NOV]Cow Relays G

原题链接

考察:矩阵快速幂+floyd最短路

思路:

        首先明白这道题不是矩阵相乘,res[i][j] = min(res[i][j],a[i][k]+b[k][j]). a[i][j]如果代表经过x条路的最短路,b[i][j]代表经过y条路的最短路.那么res是经过x+y条路的最短路.

注意:

        图上的点需要经过离散化,自环的路径不需要为0.因为n至少为1.

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cstdio>
 5 using namespace std;
 6 const int N = 1010,M = 110,INF=  0x3f3f3f3f;
 7 int n,t,s,e,idx;
 8 int g[M][M],mp[M][M],h[N];
 9 void mul(int f[][M],int a[][M])
10 {
11     int res[M][M];
12     memset(res,INF,sizeof res);
13     for(int k=1;k<=idx;k++)
14       for(int i=1;i<=idx;i++)
15         for(int j=1;j<=idx;j++)
16           res[i][j] = min(res[i][j],f[i][k]+a[k][j]);
17     memcpy(f,res,sizeof res);
18 }
19 int main()
20 {
21     scanf("%d%d%d%d",&n,&t,&s,&e);
22     memset(g,INF,sizeof g);
23     while(t--) 
24     {
25         int u,v,w; scanf("%d%d%d",&w,&u,&v);
26         if(!h[u]) h[u] = ++idx;
27         if(!h[v]) h[v] = ++idx;
28         g[h[u]][h[v]] = min(g[h[u]][h[v]],w);
29         g[h[v]][h[u]] = g[h[u]][h[v]];
30     }
31     memcpy(mp,g,sizeof g);
32     n--;
33     while(n)
34     {
35         if(n&1) mul(g,mp);
36         mul(mp,mp);
37         n>>=1;
38     }
39     printf("%d\n",g[h[s]][h[e]]);
40     return 0;
41 }

 

posted @ 2021-03-02 21:07  acmloser  阅读(88)  评论(0编辑  收藏  举报