Poj--2132(搜索,剪枝)
2014-12-18 21:41:33
思路:暴力搜索,然后注意如果发现当前最小公倍数已经是当前的最大公约数的倍数,那么就不用再搜索下去了。(吐槽下题面...其实用long long 就可以水过了,不用高精度)
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <iostream> 11 #include <algorithm> 12 using namespace std; 13 #define lp (p << 1) 14 #define rp (p << 1|1) 15 #define getmid(l,r) (l + (r - l) / 2) 16 #define MP(a,b) make_pair(a,b) 17 typedef long long ll; 18 typedef unsigned long long ull; 19 const int INF = 1 << 30; 20 const int maxn = 30; 21 22 ll ans; 23 int n; 24 int first[maxn],next[maxn * maxn],w[maxn * maxn],ver[maxn * maxn],ecnt; 25 int vis[maxn]; 26 27 ll Gcd(ll a,ll b){return b == 0 ? a : Gcd(b,a % b);} 28 ll Lcm(ll a,ll b){return a / Gcd(a,b) * b;} 29 30 void Init(){ 31 memset(first,-1,sizeof(first)); 32 ecnt = 0; 33 } 34 35 void Add_edge(int u,int v,int f){ 36 next[++ecnt] = first[u]; 37 ver[ecnt] = v; 38 w[ecnt] = f; 39 first[u] = ecnt; 40 } 41 42 void Dfs(int p,ll c){ 43 if(ans % c == 0) return; 44 if(p == 2){ 45 ans = Lcm(ans,c); 46 return; 47 } 48 for(int i = first[p]; i != -1; i = next[i]){ 49 int v = ver[i]; 50 if(vis[v]) continue; 51 vis[v] = 1; 52 Dfs(v,Gcd(c,(ll)w[i])); 53 vis[v] = 0; 54 } 55 } 56 57 int main(){ 58 int val; 59 while(scanf("%d",&n) != EOF){ 60 Init(); 61 for(int i = 1; i <= n; ++i){ 62 for(int j = 1; j <= n; ++j){ 63 scanf("%d",&val); 64 if(val != 0) Add_edge(i,j,val); 65 } 66 } 67 vis[1] = 1; 68 ans = 1; 69 for(int i = first[1]; i != -1; i = next[i]){ 70 int v = ver[i]; 71 vis[v] = 1; 72 Dfs(v,w[i]); 73 vis[v] = 0; 74 } 75 printf("%I64d\n",ans); 76 } 77 return 0; 78 }