UVALive 7231 Odd Cycle

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5243

Recently, a smart student SeoJin realized that not a few hard problems for general undirected graphsare polynomially solvable for graphs that have no cycles of odd length. Wondering whether or notthe same follows for directed graphs, she made up her mind to start a study on the subject under thesupervision of HyeongSeok, a distinguished scholar in this field. Her first research finding is effectiverecognition of the directed graphs without odd cycles, i.e., an algorithm for determining if a givendirected graph has a cycle of odd length. Still, she is promoting utmost efficiency in recognizing herclass of graphs. In order to help her, you are going to write an ultra-efficient program that determinesthe existence of an odd cycle in a directed graph and report an arbitrary odd cycle, if any.

Let G be a simple directed graph having no self-loops or multiple edges. For any two vertices v andw of G, a (directed) path from v to w in G is a sequence (u1, u2, . . . , ul) of distinct vertices of G suchthat u1 = v, ul = w, and uiis adjacent to ui+1 in G for all i ∈ {1, . . . , l −1}. If l ≥ 2 and ulis adjacentto u1, the sequence is called a (directed) cycle. An odd cycle refers to a cycle of odd length, where thelength of a cycle is simply the number of edges of the cycle. Refer to Figure 1 for illustrative examples.

 这里写图片描述

Figure 1. Simple directed graphs.
Input
Your program is to read from standard input. The input consists of T test cases, where the positiveinteger T is given in the first line of the input, followed by the description of each test case. The first lineof a test case contains two positive integers n and m, respectively, indicating the numbers of verticesand directed edges in a simple directed graph, in which we assume n ≤ 100, 000 and m ≤ 1, 000, 000.The vertices are indexed 1 to n. In the following m lines, each line contains two integers v and w, whichrepresent a directed edge from vertex v to vertex w. The two integers given in a single line are alwaysseparated by a space.
Output
Your program is to write to standard output. For each test case, the first line must contain an integerindicating whether the given directed graph has an odd cycle. If yes, the integer must be ‘1’; otherwise‘-1’. When and only when the first line is ‘1’, it must be followed by the description of an arbitrary oddcycle of the input graph. A cycle is described by a single line containing an integer l, representing itslength, followed by l lines containing, one by one, the vertices encountered when we traverse the cyclestarting from an arbitrary vertex. Note that the vertices of the cycle must be distinct.

The following shows sample input and output for four test cases.

Sample Input

4

3 3

2 3
2 1
1 3
3 4
2 3
3 2
1 2
1 3
3 4
2 1
2 3
1 3
3 2
8 9
1 2
2 3
3 4
4 1
5 6
6 7
7 8
8 5
5 8
Sample Output
-1
-1

1

3

2

1

3

-1

提示

题意:

它的目的就是让你在有向图中找出点为奇数个的环,先输出"1",并输出它的点数量,且只需要在保证点的输出符合题目所给出边的方向,输出任意顺序即可。如有多组环输出一个即可,否则输出"-1"。

思路:

深搜的基本应用,搜索+回溯找出环,并判断点的个数是否为奇数个。

示例程序

#include <stdio.h>
#include <string.h>
struct
{
    int v,next;
}w[1000000];
int h[100000],numw,top,point[100000],v[100000],bug;
void insert(int u,int v)
{
    w[numw].v=v;
    w[numw].next=h[u];
    h[u]=numw;
    numw++;
}
void dfs(int pos,int deep,int s)
{
    int i;
    for(i=h[pos];i!=-1&&bug==0;i=w[i].next)
    {
        if(v[w[i].v]==0)
        {
            v[w[i].v]=1;
            point[deep]=w[i].v;
            dfs(w[i].v,deep+1,s);
            v[w[i].v]=0;				//回溯
        }
        else if(s==w[i].v&&deep%2==1)			//判断环
        {
            bug=1;
            top=deep;
        }
    }
}
int main()
{
    int t,i,i1,n,m,x,y;
    scanf("%d",&t);
    for(i=1;t>=i;i++)
    {
        memset(h,-1,sizeof(h));
        memset(v,0,sizeof(v));
        numw=0;
        bug=0;
        scanf("%d %d",&n,&m);
        for(i1=1;m>=i1;i1++)
        {
            scanf("%d %d",&x,&y);
            insert(x-1,y-1);
        }
        for(i1=0;n>i1;i1++)
        {
            v[i1]=1;
            point[0]=i1;
            dfs(i1,1,i1);
            if(bug==1)
            {
                break;
            }
        }
        if(bug==1)
        {
            printf("1\n%d\n",top);
            for(i1=0;top>i1;i1++)
            {
                printf("%d\n",point[i1]+1);
            }
        }
        else
        {
            printf("-1\n");
        }
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值