http://www.codeforces.com/problemset/problem/117/C
昨天多校联合的题,有人发现在cf上也有,于是立刻去水水。
此题可以一遍拓扑排序判环求解 即只需要找到一个环,就必定存在三元环 证明如下: 假设存在一个n元环,因为a->b有边,b->a必定没边,反之也成立 所以假设有环上三个相邻的点a-> b-> c,那么如果c->a间有边,就已经形成了一个三元环,如果c->a没边,那么a->c肯定有边,这样就形成了一个n-1元环。。。。
所以只需证明n为4时一定有三元环即可,显然成立
ps:好像是个结论。。。竞赛图中只要有环,就肯定存在三元环
这题要输出路径,但是对拓扑排序毫无压力
#include<cstdio> #include<cstring> #include<queue> #include<vector> #include<algorithm> using namespace std; void Max(double &a,double b){if(b>a) a=b;} const int inf = ~0u>>2; const int maxn = 5010; char mp[maxn][maxn]; int n,m; vector<int> edge[maxn]; int c[maxn]; int topo[maxn]; int T; int ans; int pre[maxn]; bool dfs(int u){ c[u]=-1; for(int i=0;i<edge[u].size();i++){ int v=edge[u][i]; pre[v]=u; if(c[v]<0) {ans=v;return false; } else if(!c[v] && !dfs(v)) return false; } c[u]=1; topo[--T]=u; return true; } bool topsort(int n){ T=n+1; memset(c,0,sizeof(c)); for(int i=1;i<=n;i++) if(!c[i]){ bool f=dfs(i); if(!f) return false; } return true; } int main() { while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++) edge[i].clear(); for(int i=1;i<=n;i++) { scanf("%s",mp[i]+1); for(int j=1;j<=n;j++) { if(mp[i][j]=='1') { edge[i].push_back(j); } } } if(!topsort(n)) { printf("%d %d %d\n",pre[pre[ans]],pre[ans],ans); } else printf("-1\n"); } return 0; }