POJ 2132 暴搜OR Floyd

题意:
给你一个邻接矩阵(n<=25)问所有1到2路径的gcd的lcm是多少。
一些经验(WA/TLE的经验):
1.
无脑暴搜

是会TLE的…….
这里写图片描述

2.
关于精度
这里写图片描述
dyf神牛说了:long long就能过 (何必再写个高精呢)

3.
是不是只有我智障把LCM写错了……

思路:

  1. 暴搜+剪枝
    显然的剪枝:若已得的LCM能够除得尽当前解。剪掉。(gcd&lcm的性质)
    然后就32msAC了……
    差距很大有木有
  2. Floyd 就可以搞(不过看看数据范围根本没有往这个方面想啊……)
    f[i][j] = lcm(f[i][j], gcd(f[i][k], f[k][j]));
    如果是新的边f[i][j]=gcd(f[i][k],f[k][j]);
    仔细想想 嗯嗯 很有道理
// by SiriusRen
#include <queue>
#include <cstdio>
#include <iostream>
#define int long long
using namespace std;
int n,map[66][66],LCM=1;
struct node{int now,reached,weight;}s;
queue<node>q;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
signed main(){
    cin>>n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            cin>>map[i][j];
    s.now=1;s.reached=2;s.weight=0;
    q.push(s);
    while(!q.empty()){
        node t=q.front();q.pop();
        if(t.weight&&LCM%t.weight==0)continue;
        if(t.now==2){
            LCM=LCM*t.weight/gcd(LCM,t.weight);
            continue;
        }
        for(int i=1;i<=n;i++)
            if(map[t.now][i]&&((1<<i)&t.reached)==0){
                s.reached=t.reached|(1<<i);
                s.now=i;
                s.weight=gcd(t.weight,map[t.now][i]);
                q.push(s);
            }
    }
    cout<<LCM;
}
// by SiriusRen
#include <iostream>
#define int long long
using namespace std;
int n,f[66][66];
int gcd(int a,int b){return b?gcd(b,a%b):a;}
signed main(){
    cin>>n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            cin>>f[i][j];
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(f[i][k]&&f[k][j]){
                    if(f[i][j])f[i][j]=f[i][j]*gcd(f[i][k],f[k][j])/gcd(gcd(f[i][k],f[k][j]),f[i][j]);
                    else f[i][j]=gcd(f[i][k],f[k][j]);
                }
    cout<<f[1][2];
}
// by SiriusRen
#include <iostream>
#define int long long
using namespace std;
int n,f[66][66];
int gcd(int a,int b){return b?gcd(b,a%b):a;}
signed main(){
    cin>>n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            cin>>f[i][j];
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(f[i][k]&&f[k][j]){
                    if(f[i][j])f[i][j]=f[i][j]*gcd(f[i][k],f[k][j])/gcd(gcd(f[i][k],f[k][j]),f[i][j]);
                    else f[i][j]=gcd(f[i][k],f[k][j]);
                }
    cout<<f[1][2];
}

这里写图片描述

(得意)竟然Code Length第一~

posted @ 2016-08-26 22:12  SiriusRen  阅读(163)  评论(0编辑  收藏  举报