您的位置:首页 > 其它

[HDU 4324] Triangle LOVE (拓扑排序,DFS)

2016-04-07 19:14 429 查看
HDU - 4324

题意是,一张有 N个点的图,保证每两个点之间有且只有一条有向边连接

求是否存在三元环

用拓扑排序判环,如果存在环,则一定存在三元环

证明如下:

不存在二元环

设存在 n(n>=3)元环 p1->p2->p3->…->pn->p1

1) 若存在边 p3->p1,则存在三元环 (p1->p2->p3->p1)

2) 若不存在 p3->p1,则必然存在 p1->p3

那么 p1->p3->…->pn->p1又构成 n-1元环

递归证明可得,如果存在环,必然存在三元环

但其实这题只要无脑DFS一遍,标记走过的点不再走

在DFS的过程中碰到环的时候判断一下深度差是否为2就好了

因为DFS一定能走出所有点所在的所有环

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std;
typedef pair<int,int> Pii;
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define LL long long
#define ULL unsigned long long
#define pow2(a) a*a
int maxx(int a,int b){return a>b?a:b;}
int minn(int a,int b){return a<b?a:b;}
int abss(int a){return a<0?(-a):a;}

const int maxn=2e3+10;
int N;
char Map[maxn][maxn];
int ind[maxn];
bool inq[maxn];
int que[maxn*4];

int main()
{
int T;
scanf("%d", &T);
for(int ck=1; ck<=T; ck++)
{
CLR(ind);CLR(inq);
scanf("%d", &N);
for(int i=0; i<N; i++)
{
scanf(" %s", Map[i]);
for(int j=0; j<N; j++) if(Map[i][j]=='1') ind[j]++;
}
int qhead=0,qtail=0;
for(int i=0; i<N; i++) if(!ind[i]) {que[++qtail]=i;}
while(qhead<qtail)
{
int u=que[++qhead];inq[u]=1;
for(int v=0; v<N; v++)
{
if(Map[u][v]=='0') continue;
ind[v]--;
if(!ind[v]) que[++qtail]=v;
}
}
bool ok=1;
for(int i=0; i<N; i++) ok&=inq[i];
printf("Case #%d: ", ck);
if(!ok) puts("Yes");
else puts("No");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: