码迷,mamicode.com
首页 > 其他好文 > 详细

Cow Relays POJ - 3613

时间:2017-10-09 12:07:55      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:ring   ++   mes   利用   快速幂   blog   min   元素   struct   

这题面是外星人写的吧

定义一个群,其元素为一个矩阵,定义一个该群的元素M,并且M存着一个图。

定义一个二元运算符*,运算结果仍为该群的元素。

如M*M=R,则R(i,j)=Min(Rij,Mik+Mkj)

这个操作满足交换律和结合律。

其意义代表不言而喻。(手动滑稽)

因此可利用快速幂求解。

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int MOD=1000;
const int sz=201;
int N,t,s,e,n;
struct mat{
    int a[sz][sz];
    mat(){memset(a,0,sizeof a);}
    void initE(){for(int i=0;i<n;i++)a[i][i]=1;}
    void initfib(){a[1][0]=a[0][1]=a[0][0]=1;a[1][1]=0;}
    mat operator*(const mat&t)const{
        mat q;memset(q.a,0x3f,sizeof q.a);
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
            for(int k=0;k<n;k++)
                q.a[i][j]=min(q.a[i][j],a[i][k]+t.a[k][j]);
        return q;
    }
    void out(){
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++)printf("%d ",a[i][j]);printf("\n");
        }
    }
    mat operator^(int k)const{
        mat res=*this;
        mat m=*this;
        //res.out();m.out();
        while(k>0){
            if(k&1)res=res*m;
            m=m*m;k>>=1;
        }
        return res;
    }

};
int mp[1010];
int main(){ 
    scanf("%d%d%d%d",&N,&t,&s,&e);
    n=0;
    for(int i=0;i<1010;i++)mp[i]=-1;
    mat m;memset(m.a,0x3f,sizeof m.a);
    while(t--){
        int l,x,y;
        scanf("%d%d%d",&l,&x,&y);
        int sx=mp[x],sy=mp[y];
        if(sx==-1)sx=mp[x]=n++;
        if(sy==-1)sy=mp[y]=n++;
        m.a[sx][sy]=m.a[sy][sx]=l;
    }
   // m.out();
    m=m^(N-1);
  //  m.out();
    printf("%d\n",m.a[mp[s]][mp[e]]);
    return 0;
}

 

Cow Relays POJ - 3613

标签:ring   ++   mes   利用   快速幂   blog   min   元素   struct   

原文地址:http://www.cnblogs.com/MeowMeowMeow/p/7640275.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!