POJ3613-恰好K步最短路

/*
从这抄来的,自己不会写,-_-!  http://hi.baidu.com/lxxstar1226/item/9119a40de25c55faa1103462
用到了矩阵相关知识,见转自Matrix67的博客:http://blog.sina.com.cn/s/blog_680c5cd50100khvp.html
*/
#include <cstdio>
#include <iostream>
#include <cstring>
#define mem(a,x) memset(a,x,sizeof(a))
using namespace std;

const int NN=205;
const int MM=1005;
const int INF=1000000001;

int n,m,S,T,vcnt;
int hash[MM],dis[NN][NN],tmp[NN][NN],f[NN][NN];

void solve(int n)  //求f[i][j],f[i][j]为从节点i到节点j的步数为n的最短路,二分n,类似于快速幂过程
{
    int i,j,k;
    while(n)
    {
        if(n%2)  //n为奇数时,n步=n/2步+n/2步+1步,这里是在补充多的一步,这一步也不是单纯的一步。。。是多出来的整个部分,如n=11时,n=(4+4)+3,多出来的部分是3步,这是因为n要拆成2^a+2^a+b,这里补上b步,后面计算2*2^a步。
        {
            for(i=1; i<=vcnt; i++)
                for(j=1; j<=vcnt; j++)
                    tmp[i][j]=INF;

            for(k=1; k<=vcnt; k++)    //n=1110  11
                for(i=1; i<=vcnt; i++)
                    for(j=1; j<=vcnt; j++)  //我擦!写成j<vcnt,WA两次
                        if(tmp[i][j]>f[i][k]+dis[k][j])
                            tmp[i][j]=f[i][k]+dis[k][j];

            for(i=1; i<=vcnt; i++)
                for(j=1; j<=vcnt; j++)
                    f[i][j]=tmp[i][j]; //最后一次n=1,一定会进行这一步
        }
        for(i=1; i<=vcnt; i++)
            for(j=1; j<=vcnt; j++)
                tmp[i][j]=INF;
        for(k=1; k<=vcnt; k++)
            for(i=1; i<=vcnt; i++)
                for(j=1; j<=vcnt; j++)
                    if(tmp[i][j]>dis[i][k]+dis[k][j])
                        tmp[i][j]=dis[i][k]+dis[k][j];  //n步=n/2步+n/2步
        for(i=1; i<=vcnt; i++)
            for(j=1; j<=vcnt; j++)
                dis[i][j]=tmp[i][j];
        n=n/2;
    }
    return ;
}

int main()
{
    vcnt=0;
    mem(hash,0);
    for (int i=0; i<NN; i++)
    {
        for (int j=0; j<NN; j++)
            f[i][j]=dis[i][j]=INF;
        f[i][i]=0;
    }
    scanf("%d%d%d%d",&n,&m,&S,&T);
    int u,v,w;
    for (int i=1; i<=m; i++)
    {
        scanf("%d%d%d",&w,&u,&v);
        if (!hash[u]) hash[u]=++vcnt;
        if (!hash[v]) hash[v]=++vcnt;
        dis[hash[u]][hash[v]]=w;
        dis[hash[v]][hash[u]]=w;
    }
    solve(n);
    printf("%d\n",f[hash[S]][hash[T]]);
    return 0;
}

你可能感兴趣的:(c,Matrix)