思路就是簡單的dfs+標號, 若發現一趟dfs中又標號差2的, 則存在三角關係.
但寫了N久還是wa....
有一個地方我覺得是有問題的, 就是在判斷標號差2的時候, 有可能v的標號是前一趟dfs的而不是當前趟dfs的,
所以v的標號就不能說明什麼問題了...這樣可能導致wa
簡言之就是要在判斷的時候保證選的v都是當前趟dfs標號的.
看了 http://blog.ac521.org/?p=502&cpage=1#comment-181 的題解,
比對了後發現我是 標號差2寫成了判斷絕對值, 而他就是預設當前是較大的(這樣沒錯, 但是不能解決我上面說的那個問題, 也就是說題目資料不完備, 能wa掉我, 不能wa掉他...?)
下面這代碼是保證標號始終遞增的, 從而解決了上述問題.
代碼:
#include<cstdio>#include<cstring>#include<iostream>#include<cmath>#include<string>#include<vector>#include<map>using namespace std;int Rint() { int x; scanf("%d", &x); return x; }#define FOR(i, a, b) for(int i=(a); i<=(b); i++)#define FORD(i,a,b) for(int i=(a);i>=(b);i--)#define REP(x) for(int i=0; i<(x); i++)typedef long long int64;#define INF (1<<30)#define bug(s) cout<<#s<<"="<<s<<" "#define MAXN 2002int G[MAXN][MAXN];int dfn[MAXN];//標號int n;int abs(int x) { return x<0? -x: x; }int idx;//當前最大標號int dfs(int u, int t){dfn[u] = t;idx = max(idx, t);int ret = 0;for(int i=0; i<n; i++) if(G[u][i]){if(!dfn[i]){ret |= dfs(i, t+1);}else{if(dfn[i] + 2==t)//若 i 是上一個連通快的, 則 dfn[i]必然小於 treturn 1;//存在 }}return ret;}int solve(){REP(n){if(!dfn[i]){if(dfs(i, idx+1))//始終從當前最大標號+1開始標記{return 1;//cunzai}}}return 0;}int main(){int t = Rint();FOR(T, 1, t){idx = 0;memset(dfn, 0,sizeof(dfn));printf("Case #%d: ", T);n = Rint();FOR(i, 0, n-1){char buf[MAXN];scanf("%s", buf);FOR(j, 0, n-1){G[i][j] = buf[j]-'0';}}if(solve())printf("Yes\n");elseprintf("No\n");}}