- 论坛徽章:
- 0
|
本帖最后由 18222936370 于 2014-03-31 15:36 编辑
回复 5# weishuo1999 - /*算法原理是:
- 每次找到第一个结点,将其提取出来并消掉其后的边,之后再找下一个节点。
- 若在所有节点并未被提取出时出现找不到当前第一个结点的情况,则存在圈。
- 此时任意一个节点沿其后的边进行查找,直至回到该节点,都是这个图中的一个圈。
- 若能顺利查找完所有结点并不存在圈,则是DAG。
- */
- /*实现方法:
- 将图想象成一个树,用depth表示某节点的深度,则所找的第一个节点应为depth为0的节点
- 当找出第一个点之后,该点的所有孩子的depth减一
- 此时再将这一点的depth变为-1,定义其为已查找过
- 某一时刻遍历时不存在depth为0的点则说明已查找完或存在圈
- 时间复杂度为O(n^2)*/
- #include<iostream>
- #include<memory>
- using namespace std;
- struct DAG
- {
- int depth;
- int *next;
- };
- int main()
- {
- int m,n,M,N;
- cin>>m>>n;
- DAG *point=new DAG[m];
- for(int i=0;i<m;i++)
- {
- point[i].depth =0;
- point[i].next =new int[m+1];
- memset(point[i].next,-1,m+1);
- /*for(int j=0;j<m+1;j++)
- {
- point[i].next[j]=-1;
- }*/
- }
- for(int i=0;i<n;i++)
- {
- cin>>M>>N;
- M--;N--;
- int x=0;
- while(point[M].next[x]!=-1 )x++;
- point[M].next[x]=N;
- point[N].depth ++;
- }
- for(int i=0;i<m;i++)
- {
- int y=0,j=0,x=0,k=0;
- for(j=0;j<m;j++)
- {
- if(point[j].depth ==0)y++;
- break;
- }
- if(y==1)
- {
- while(point[j].next[x]!=-1)
- {
- point[point[j].next[x]].depth --;
- };
- point[j].depth =-1;
- }
- if(y==0)
- {
- cout<<"No"<<endl;
- break;
- }
- if(y==1&&i==(m-1))cout<<"Yes"<<endl;
- }
- return 0;
- }
复制代码 题目就是判断一个图是否是有向无圈图,这是我写的代码。
给的样例输入是
5 7(第一个为结点数 第二个为边数)
1 2(第一个是根结点,第二个是指向的结点)
1 3
2 1
2 5
3 4
4 2
4 5
输出是 No
如果换成注释的for的那一段就可以执行。 |
|