Codeforces 263 C. Circle of Numbers D. Cycle in Graph (dfs一般难度)

C. Circle of Numbers
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

One day Vasya came up to the blackboard and wrote out n distinct integers from 1 to n in some order in a circle. Then he drew arcs to join the pairs of integers (a, b) (a ≠ b), that are either each other's immediate neighbors in the circle, or there is number c, such that aand с are immediate neighbors, and b and c are immediate neighbors. As you can easily deduce, in the end Vasya drew n arcs.

For example, if the numbers are written in the circle in the order 1, 2, 3, 4, 5 (in the clockwise direction), then the arcs will join pairs of integers (1, 2)(2, 3)(3, 4)(4, 5)(5, 1)(1, 3)(2, 4)(3, 5)(4, 1) and (5, 2).

Much time has passed ever since, the numbers we wiped off the blackboard long ago, but recently Vasya has found a piece of paper withn written pairs of integers that were joined with the arcs on the board. Vasya asks you to find the order of numbers in the circle by these pairs.

Input

The first line of the input contains a single integer n (5 ≤ n ≤ 105) that shows, how many numbers were written on the board. Next nlines contain pairs of integers aibi (1 ≤ ai, bi ≤ nai ≠ bi) — the numbers that were connected by the arcs.

It is guaranteed that no pair of integers, connected by a arc, occurs in the input more than once. The pairs of numbers and the numbers in the pairs are given in the arbitrary order.

Output

If Vasya made a mistake somewhere and there isn't any way to place numbers from 1 to n on the circle according to the statement, then print a single number "-1" (without the quotes). Otherwise, print any suitable sequence of n distinct integers from 1 to n.

If there are multiple solutions, you are allowed to print any of them. Specifically, it doesn't matter which number you write first to describe the sequence of the order. It also doesn't matter whether you write out the numbers in the clockwise or counter-clockwise direction.

Sample test(s)
input
5
1 2
2 3
3 4
4 5
5 1
1 3
2 4
3 5
4 1
5 2
output
1 2 3 4 5 
input
6
5 6
4 3
5 3
2 4
6 1
3 1
6 2
2 5
1 4
3 6
1 2
4 5
output
1 2 4 5 3 6 

http://codeforces.com/contest/263/problem/C


//Hello. I'm Peter.
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<cctype>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double ld;
#define peter cout<<"i am peter"<<endl
#define input freopen("data.txt","r",stdin)
#define randin srand((unsigned int)time(NULL))
#define INT (0x3f3f3f3f)*2
#define LL (0x3f3f3f3f3f3f3f3f)*2
#define gsize(a) (int)a.size()
#define len(a) (int)strlen(a)
#define slen(s) (int)s.length()
#define pb(a) push_back(a)
#define clr(a) memset(a,0,sizeof(a))
#define clr_minus1(a) memset(a,-1,sizeof(a))
#define clr_INT(a) memset(a,INT,sizeof(a))
#define clr_true(a) memset(a,true,sizeof(a))
#define clr_false(a) memset(a,false,sizeof(a))
#define clr_queue(q) while(!q.empty()) q.pop()
#define clr_stack(s) while(!s.empty()) s.pop()
#define rep(i, a, b) for (int i = a; i < b; i++)
#define dep(i, a, b) for (int i = a; i > b; i--)
#define repin(i, a, b) for (int i = a; i <= b; i++)
#define depin(i, a, b) for (int i = a; i >= b; i--)
#define pi 3.1415926535898
#define eps 1e-6
#define MOD 1000000007
#define MAXN
#define N 100100
#define M 200
struct Edge
{
    int to,from;
    int next;
}edge[4*N];//这里要开4倍呀!很坑
int head[N],app[N];
int n,a,b,w;
void add_edge(int from,int to)
{
    w++;
    edge[w].from=from;
    edge[w].to=to;
    edge[w].next=head[from];
    head[from]=w;
}
bool ok;
void print()
{//如果不成立输出-1
    if(ok) return;
    printf("-1\n");
    exit(0);
}
queue<int>q;
bool dfs(int grandf,int fa,int son)
{
    q.push(son);
    if(q.size()>n) return false;
    int i,to,j,jto,sum=0,w=0;
    bool hasgrandf=false;
    //对于两个点来说,都有2个公共点,把这两个公共点找出来
    for(i=head[fa];i!=-1;i=edge[i].next)
    {
        to=edge[i].to;
        for(j=head[son];j!=-1;j=edge[j].next)
        {
            jto=edge[j].to;
            if(to==jto)
            {
                sum++;
                if(to==grandf) hasgrandf=true;
                else w=to;
            }
        }
    }
    //一定有2个公共点,并且一个是之前过来的祖父点,一个是孙子点
    if(sum!=2 || !hasgrandf) return false;
    else if(w==1 && q.size()==n) return true;
    else if(w==1 && q.size()!=n) return false;
    //当孙子点是1的时候,这时如果队列有n个元素,那么就恰好转了一圈,符合题意了
    return dfs(fa,son,w);
}
int son[N],num;
int main()
{
    ok=true;
    cin>>n;
    clr_minus1(head);
    w=0;
    repin(i,1,2*n)
    {
        scanf("%d %d",&a,&b);
        add_edge(a,b);
        add_edge(b,a);
        app[a]++;
        app[b]++;
    }
    //每个点都只有4个其他点和它相连
    repin(i,1,n)
    {
        if(app[i]!=4)
        {
            ok=false;
            break;
        }
    }
    print();
    if(n==5)
    {
        printf("1 2 3 4 5\n");
        exit(0);
    }
    int i,to;
    num=0;
    for(i=head[1];i!=-1;i=edge[i].next)
    {
        to=edge[i].to;
        num++;
        son[num]=to;
    }
    ok=false;
    //枚举4个和点1相连的点,12种情况 dfs判断是否成立
    repin(i,1,num)
    {
        if(ok) break;
        repin(j,1,num)
        {
            if(i==j) continue;
            clr_queue(q);
            q.push(1);
            q.push(son[i]);
            ok=dfs(1,son[i],son[j]);
            if(ok) break;
            
            clr_queue(q);
            q.push(1);
            q.push(son[j]);
            ok=dfs(1,son[j],son[i]);
        }
    }
    print();
    bool first=true;
    while(!q.empty())
    {
        if(first) first=false;
        else printf(" ");
        int t=q.front();
        printf("%d",t);
        q.pop();
    }
    printf("\n");
}




D. Cycle in Graph
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You've got a undirected graph G, consisting of n nodes. We will consider the nodes of the graph indexed by integers from 1 to n. We know that each node of graph G is connected by edges with at least k other nodes of this graph. Your task is to find in the given graph a simple cycle of length of at least k + 1.

simple cycle of length d (d > 1) in graph G is a sequence of distinct graph nodes v1, v2, ..., vd such, that nodes v1 and vd are connected by an edge of the graph, also for any integer i (1 ≤ i < d) nodes vi and vi + 1 are connected by an edge of the graph.

Input

The first line contains three integers nmk (3 ≤ n, m ≤ 105; 2 ≤ k ≤ n - 1) — the number of the nodes of the graph, the number of the graph's edges and the lower limit on the degree of the graph node. Next m lines contain pairs of integers. The i-th line contains integersaibi (1 ≤ ai, bi ≤ nai ≠ bi) — the indexes of the graph nodes that are connected by the i-th edge.

It is guaranteed that the given graph doesn't contain any multiple edges or self-loops. It is guaranteed that each node of the graph is connected by the edges with at least k other nodes of the graph.

Output

In the first line print integer r (r ≥ k + 1) — the length of the found cycle. In the next line print r distinct integers v1, v2, ..., vr (1 ≤ vi ≤ n)— the found simple cycle.

It is guaranteed that the answer exists. If there are multiple correct answers, you are allowed to print any of them.

Sample test(s)
input
3 3 2
1 2
2 3
3 1
output
3
1 2 3 
input
4 6 3
4 3
1 2
1 3
1 4
2 3
2 4
output
4
3 4 1 2 

http://codeforces.com/contest/263/problem/D


//Hello. I'm Peter.
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<cctype>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double ld;
#define peter cout<<"i am peter"<<endl
#define input freopen("data.txt","r",stdin)
#define INT (0x3f3f3f3f)*2
#define LL (0x3f3f3f3f3f3f3f3f)*2
#define gsize(a) (int)a.size()
#define len(a) (int)strlen(a)
#define slen(s) (int)s.length()
#define pb(a) push_back(a)
#define clr(a) memset(a,0,sizeof(a))
#define clr_minus1(a) memset(a,-1,sizeof(a))
#define clr_INT(a) memset(a,INT,sizeof(a))
#define clr_true(a) memset(a,true,sizeof(a))
#define clr_false(a) memset(a,false,sizeof(a))
#define clr_queue(q) while(!q.empty()) q.pop()
#define clr_stack(s) while(!s.empty()) s.pop()
#define rep(i, a, b) for (int i = a; i < b; i++)
#define dep(i, a, b) for (int i = a; i > b; i--)
#define repin(i, a, b) for (int i = a; i <= b; i++)
#define depin(i, a, b) for (int i = a; i >= b; i--)
#define pi 3.1415926535898
#define eps 1e-6
#define MOD 1000000007
#define MAXN
#define N 100100
#define M
int n,m,k;
struct Edge
{
    int from,to;
    int next;
}edge[2*N];
int head[N];
int w,a,b;
void add_edge(int from,int to)
{
    w++;
    edge[w].from=from;
    edge[w].to=to;
    edge[w].next=head[from];
    head[from]=w;
}
stack<int>st;
int step[N],limit,num;
bool quit;
void dfs(int now,int sum)
{
    step[now]=sum;
    st.push(now);
    int i,to;
    for(i=head[now];i!=-1;i=edge[i].next)
    {
        to=edge[i].to;
        if(!step[to])
        {
            dfs(to,sum+1);
            if(!quit)
            {
                int t=st.top();
                st.pop();
                step[t]=0;
                //注意这里
                //当点从栈中出来的时候,一定要记录一下,这里是将step[t]清为0,否则会wrong!
            }
            else return;
        }
        //如果满足下面这个式子,那就说明已经形成一圈,并且这一圈中的顶点个数>=k+1
        //那就符合题意啦!
        else if(step[now]-step[to]+1>=k+1)
        {
            quit=true;
            limit=to;
            num=step[now]-step[to]+1;
            return;
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    w=0;
    clr_minus1(head);
    repin(i,1,m)
    {
        scanf("%d %d",&a,&b);
        add_edge(a,b);
        add_edge(b,a);
    }
    clr(step);
    quit=false;
    dfs(1,1);
    bool first=true;
    printf("%d\n",num);
    while(!st.empty())
    {
        if(first) first=false;
        else printf(" ");
        int t=st.top();
        printf("%d",t);
        st.pop();
        //达到一圈就停止
        if(t==limit) break;
    }
    printf("\n");
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值