HDU-4324 Triangle LOVE 拓扑排序
对于这样一道有着如此强烈限制条件的题目(任意两个点一定有边,而且是单向边),表示拥有各种解法,甚至连随机化的方法的AC率都不会太低。
这里考虑到不会存在二个点成环的情况,那么我们要论证的就是三个以上的点成环那么就一定有三个点能够成环。对于N个点成环的情况,我们可以选取连续的三个点,如果两边的两个点的边的方向刚好使得三个点成环的话,那么就说明我们的假设成立,如果不是的话,那么就变成了N-1个点成环,以此类推,就一定能够找到3个构成的一个环。
代码如下:
#include <cstdlib> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; int N, de[2005], que[2005], tail, front; char R[2005][2005]; bool Topo() { int pos, cnt = 0; tail = front = 0; for (int i = 1; i <= N; ++i) { if (de[i] == 0) { que[++tail] = i; } } if (front == tail) { return true; } while (front != tail) { pos = que[++front]; ++cnt; for (int i = 1; i <= N; ++i) { if (R[pos][i] == '1') { --de[i]; if (de[i] == 0) { que[++tail] = i; } } } } return cnt == N ? false : true; } int main() { int T, ca = 0; scanf("%d", &T); while (T--) { scanf("%d", &N); memset(de, 0, sizeof (de)); for (int i = 1; i <= N; ++i) { scanf("%s", R[i]+1); for (int j = 1; j <= N; ++j) { if (R[i][j] == '1') { ++de[j]; } } } printf("Case #%d: ", ++ca); printf(Topo() ? "Yes\n" : "No\n"); } return 0; }