I - Walk of Three(dfs)

本文探讨了一个编程问题,涉及Vasya在公园中遵循规则进行安全行走的路径选择。通过指定的起始点和路径限制,计算Vasya能尝试的不同行走路线数。使用DFS算法和优化,解决如何找到三条不同的路径,确保最终到达的安全区域。
摘要由CSDN通过智能技术生成

题目描述

The city where Vasya lives has a park with nn lawns connected by mm paths. One can walk in both directions along each path. The lawns connected by the path are called neighbors.

The entrance to the park is near the lawn number one which will be called the entrance lawn. Vasya’s parents are very concerned about his safety, so they allow him to play only on the lawn that is a neighbor to the entrance lawn. Entrance lawn is usually overcrowded, so Vasya can’t play on it.

Vasya finds it boring to simply walk along the path to the neighbor lawn. Instead, he starts at the entrance lawn, and walks along exactly three different paths. After that he plays on the lawn where he ends his walk. Vasya does not break the rules set by the parents, so he always ends his walk on the lawn neighboring to the entrance lawn.

Every day Vasya wants to choose a new walk he hasn’t taken before. Help him to determine how many ways are to begin his journey at the entrance lawn, follow exactly three different paths, and find himself on the lawn neighboring to the entrance lawn.

Input
The first line of input contains two integers nn and mm — the number of lawns and the number of paths, respectively (1≤n≤1000001≤n≤100000, 1≤m≤2000001≤m≤200000).

The next mm lines contain pairs of lawns connected by paths. Any two lawns are connected by no more than one path. There are no paths connecting a lawn to itself.

Output
Print the number of walks that Vasya can take.

Examples
Input
10 14
1 5
2 5
5 6
2 3
1 3
2 4
4 6
1 6
1 7
7 8
8 1
1 10
9 10
9 8
Output
4
Input
3 3
1 2
2 3
3 1
Output
0

题目大意

一个人要从开始点(1)连续走三条互不相同的路,确保最后到达的点可以到达开始点或者最后直接到达开始点。

AC代码

这个题硬上dfs直接TLE,稍微修改了一下,卡时间AC。
应该是还可以再剪枝的,希望大佬评论指点。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int sum,n,m;
int vis[101000]= {0};
int dis[101000]= {0};
vector<int>a[100010];
void dfs(int x,int cnt)
{
    vis[x]=1;
    if(cnt==3)
    {
        if(dis[x]==1)sum++;
        return ;
    }
    int len=a[x].size();
    for(int i=0; i<len; i++)
    {
        if(!vis[a[x][i]])
        {
            cnt++;
            dfs(a[x][i],cnt);
            cnt--;
            vis[a[x][i]]=0;
        }
    }
}
int main()
{
    scanf("%d %d",&n,&m);
    for(int i=0; i<m; i++)
    {
        int u,v;
        scanf("%d %d",&u,&v);
        if(u==1)dis[v]=1;
        if(v==1)dis[u]=1;
        a[u].push_back(v);
        a[v].push_back(u);
    }
    sum=0;
    dfs(1,0);
    cout<<sum<<endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值