标签:
先给个任意门:
http://train.usaco.org/usacoprob2?a=Hjk3nSx2aDB&S=wormhole
又是一道好题
直接解释吧~
x,y -> position
r[u] -> 第u个点右边第一个hole的位置
partner[u] -> 与u相连的点
Then 怎么判断她就陷入循环了呢?
也就是以下代码中n-1次判断走过虫洞并判断虫洞。
pos表示从第pos个虫洞进入,进入后,我们自然就到达了 partener [pos]
那下一个位置就是 r[ partener[pos] ]
所以 pos=r[ partener[pos]] 即可。实现不断的循环了!
then 这样循环n-1次之后 判断pos 是否为0,为0就表示并没有循环,已经成功走出去了~
不是0就当然代表已经遭定了。本题主体就是这样了。
宝贵的一点,本题用到的回溯相当的巧妙,细细enjoy以下.~
下附代码:
#include <iostream> #include <list> #include <map> #include <math.h> #include <string.h> #include <string> #include <fstream> #include <algorithm> using namespace std; ifstream fin("wormhole.in"); ofstream fout("wormhole.out"); int n, res; int partner[14]; int x[14], y[14], r[14]; bool cycle_exist() { for (int i = 1; i <= n; i++) { int pos = i; for (int j = 1; j < n; j++) { pos = r[partner[pos]]; } if (pos != 0) return true; } return false; } int solve() { int i; int total = 0; for (i = 1; i <= n; i++) { if (partner[i] == 0) break; } if (i >= n) { if (cycle_exist()) return 1; else return 0; } for (int j = i+1; j <= n; j++) { if (partner[j] == 0) { partner[i] = j; partner[j] = i; total += solve(); partner[i] = partner[j] = 0; } } return total; } int main() { fin >> n; for (int i = 1; i <= n; i++) { fin >> x[i] >> y[i]; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (x[j] > x[i] && y[j] == y[i]) { if (r[i] == 0 || x[j] - x[i] < x[r[i]] - x[i]) { r[i] = j; } } } } fout << solve() << endl; return 0; }
标签:
原文地址:http://www.cnblogs.com/cherry231/p/5153661.html