Cow Relays POJ

来源:互联网 发布:淘宝秒杀怎么抢 编辑:程序博客网 时间:2024/06/05 07:19

本题的大意就是问从S 到 T 经过边得个数恰为k的最短路是多少。

如果学过离散数学 就应该知道 邻接矩阵A
A^1里的元素a[i][j] 代表i到j的走一步一条路;
A^2里的元素a[i][j] 代表i到j的走两步一条路 ;
A^n里的元素a[i][j] 代表i到j的走N步一条路 ;
然后再矩阵快速幂一下就好

代码如下

/* * Author       :  Echo * Email        :  1666424499@qq.com   * Description  :    * Created Time :  2017/10/6 18:08:21 * Last Modify  :  2017/10/6 19:02:49 * File Name    :  a.cpp */#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>#include <string>#include <vector>#include <stack>#include <queue>#include <set>#include <time.h>#define LL long long#define mem(a,k) memset(a,k,sizeof(a))#include <map>using namespace std;const int maxint = -1u>>1;const int maxn=2e2+100;const int maxm=1e4+100;int cnt=0;struct node{    int an[maxn][maxn];    void set(){        for(int i=1;i<=200;i++)            for(int j=1;j<=200;j++)                an[i][j]=1e9;    }    void copy(node a){        for(int i=1;i<=cnt;i++)            for(int j=1;j<=cnt;j++)                an[i][j]=a.an[i][j];    }    node cal(node a,node b){        node res;        res.set();        for(int i=1;i<=cnt;i++)            for(int k=1;k<=cnt;k++)                for(int j=1;j<=cnt;j++)                    if(res.an[i][j]>a.an[i][k]+b.an[k][j])                       res.an[i][j]=a.an[i][k]+b.an[k][j];        return res;    }}road,ans;void QSM(int n){    ans.copy(road);    n--;    while(n){        if(n%2==1){            ans=ans.cal(ans,road);        }        road=road.cal(road,road);        n>>=1;    }}int main(){    int n,m,s,t;    cin>>n>>m>>s>>t;    map<int,int >mp;    road.set();    for(int i=1;i<=m;i++){        int a,b,c;        cin>>c>>a>>b;        if(mp[a]==0)mp[a]=++cnt;        if(mp[b]==0)mp[b]=++cnt;        //printf("%d:%d;%d:%d %d\n",a,mp[a],b,mp[b],road.an[mp[a]][mp[b]]);        if(road.an[mp[a]][mp[b]]>c){            road.an[mp[a]][mp[b]]=c;            road.an[mp[b]][mp[a]]=c;        }    }    QSM(n);    //printf("%d %d\n",mp[s],mp[t]);    printf("%d\n",ans.an[mp[s]][mp[t]]);    return 0;}/*2 6 6 411 4 64 4 88 4 96 6 82 6 93 8 910  */
原创粉丝点击