牛客周赛 Round 89(A~G)

F想dp去了,F写完,G还有10分钟,只能感叹情况考虑不周了

A.小红开灯(一)

思路:签到,无需多言

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<cstring>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#include<bitset>
#define ll                           long long 
// #define lowbit(x) (x & -x)
//#define endl "\n"//                           交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)//快速幂
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
ll gcd(ll x, ll y)
{
    if (y == 0)
        return x;
    else
        return gcd(y, x % y);
}
ll lcm(ll x, ll y)
{
    x /= gcd(x, y);
    return y * x;
}
// inline ll read()//快读
// {
//     register ll x = 0, f = 1;
//     char c = getchar();
//     while (c < '0' || c>'9')
//     {
//         if (c == '-') f = -1;
//         c = getchar();
//     }
//     while (c >= '0' && c <= '9')
//     {
//         x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速
//         c = getchar();
//     }
//     return x * f;
// }
struct ss
{
    ll v, id;
    friend bool operator<(const ss& a, const ss& b)
    {
        return a.v < b.v;
    };
};
void fio()//加速流
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
ll e1[8] = { 0,1,0,-1,1,1,-1,-1 };
ll e2[8] = { 1,0,-1,0,1,-1,-1,1 };//前面四个为上下左右,后面四个为角落
int main()
{
    fio();
    ll t;
    // t=1;
    cin >> t;
    while (t--)
    {
      ll n;
      cin>>n;
      cout<<(n+1)/2<<endl;
    }
    return 0;
}

B.小红开灯(二)

思路:只需考虑连续的1段即可,答案为每个1的连续段长度/2

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<cstring>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#include<bitset>
#define ll                           long long 
// #define lowbit(x) (x & -x)
//#define endl "\n"//                           交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)//快速幂
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
ll gcd(ll x, ll y)
{
    if (y == 0)
        return x;
    else
        return gcd(y, x % y);
}
ll lcm(ll x, ll y)
{
    x /= gcd(x, y);
    return y * x;
}
// inline ll read()//快读
// {
//     register ll x = 0, f = 1;
//     char c = getchar();
//     while (c < '0' || c>'9')
//     {
//         if (c == '-') f = -1;
//         c = getchar();
//     }
//     while (c >= '0' && c <= '9')
//     {
//         x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速
//         c = getchar();
//     }
//     return x * f;
// }
struct ss
{
    ll v, id;
    friend bool operator<(const ss& a, const ss& b)
    {
        return a.v < b.v;
    };
};
void fio()//加速流
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
ll e1[8] = { 0,1,0,-1,1,1,-1,-1 };
ll e2[8] = { 1,0,-1,0,1,-1,-1,1 };//前面四个为上下左右,后面四个为角落
int main()
{
    fio();
    ll t;
     t=1;
   // cin >> t;
    while (t--)
    {
        ll n;
        string f;
        cin>>n>>f;
        ll cnt=0;
        ll ans=0;
        for(ll i=0;i<f.size();i++)
        {
        if(f[i]=='1')
        {
            cnt++;
        }
        else 
        {
            ans+=cnt/2;
            cnt=0;
        }
        }
        ans+=cnt/2;
        cout<<ans<<endl;
    }
    return 0;
}

C.小红开灯(三,easy)

思路:简单dp,dp为灯数为i时的状态数,设dp[0]=1,可以认为灯为0也是一种情况,然后当k<i,时dp[i]=dp[i-1],你不能进行任何操作,所以答案得继承.当i>=k时,dp[i]=dp[i-1]*2,这里你可以认为以i为末尾时使用一次操作和不使用一次操作各创造了一种情况。此时乘2即可,不操作是继承,操作是在原来的基础上复制了一遍并改变了最后k个数。如此答案得出

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<cstring>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#include<bitset>
#define ll                           long long 
// #define lowbit(x) (x & -x)
//#define endl "\n"//                           交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)//快速幂
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
ll gcd(ll x, ll y)
{
    if (y == 0)
        return x;
    else
        return gcd(y, x % y);
}
ll lcm(ll x, ll y)
{
    x /= gcd(x, y);
    return y * x;
}
// inline ll read()//快读
// {
//     register ll x = 0, f = 1;
//     char c = getchar();
//     while (c < '0' || c>'9')
//     {
//         if (c == '-') f = -1;
//         c = getchar();
//     }
//     while (c >= '0' && c <= '9')
//     {
//         x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速
//         c = getchar();
//     }
//     return x * f;
// }
struct ss
{
    ll v, id;
    friend bool operator<(const ss& a, const ss& b)
    {
        return a.v < b.v;
    };
};
void fio()//加速流
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
ll e1[8] = { 0,1,0,-1,1,1,-1,-1 };
ll e2[8] = { 1,0,-1,0,1,-1,-1,1 };//前面四个为上下左右,后面四个为角落
int main()
{
    fio();
    ll t;
     t=1;
   // cin >> t;
    while (t--)
    {
        ll n,k;
        cin>>n>>k;
        vector<ll>dp(n+5);
        dp[0]=1;
        for(ll i=1;i<=n;i++)
        {
            dp[i]=dp[i-1];
            if(i>=k)dp[i]*=2;
            dp[i]%=mod;
        }
        //cout<<dp[2]<<endl;
        cout<<dp[n]<<endl;
    }
    return 0;
}

D.小红开灯(三,hard)

思路:k是随机改变的,不妨自己手动枚举下,k=n时,答案为2,这个不用说了。k是奇数时,答案就是2的n次方,否则答案就是2的n次方除以2。奇数可以想想我最后可以造成只改变一个数,所以在这基础上,我又可以单独改变一个数,所以什么答案都能创造出.偶数会发现某一时刻时,他只能创造一个关灯数为等差数列的可能情况,显然答案时2的n-1次方(可以手动枚举下)。

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<cstring>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#include<bitset>
#define ll                           long long 
// #define lowbit(x) (x & -x)
//#define endl "\n"//                           交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)//快速幂
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
ll gcd(ll x, ll y)
{
    if (y == 0)
        return x;
    else
        return gcd(y, x % y);
}
ll lcm(ll x, ll y)
{
    x /= gcd(x, y);
    return y * x;
}
// inline ll read()//快读
// {
//     register ll x = 0, f = 1;
//     char c = getchar();
//     while (c < '0' || c>'9')
//     {
//         if (c == '-') f = -1;
//         c = getchar();
//     }
//     while (c >= '0' && c <= '9')
//     {
//         x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速
//         c = getchar();
//     }
//     return x * f;
// }
struct ss
{
    ll v, id;
    friend bool operator<(const ss& a, const ss& b)
    {
        return a.v < b.v;
    };
};
void fio()//加速流
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
ll e1[8] = { 0,1,0,-1,1,1,-1,-1 };
ll e2[8] = { 1,0,-1,0,1,-1,-1,1 };//前面四个为上下左右,后面四个为角落
int main()
{
    fio();
    ll t;
     t=1;
   // cin >> t;
    while (t--)
    {
        ll n,k;
        cin>>n>>k;
        vector<ll>f(n+5);
        f[0]=1;
        for(ll i=1;i<=n;i++)f[i]=f[i-1]*i%mod;
        // vector<ll>dp(n+5);   
        // dp[0]=1;
        // for(ll i=1;i<=n;i++)
        // {
        //     dp[i]=dp[i-1];
        //     if(i>=k)dp[i]*=2;
        //     dp[i]%=mod;
        // }
        // //cout<<dp[2]<<endl;
        // cout<<dp[n]<<endl;
        if(n==k)
        {
            cout<<2<<endl;
        }
        else if(k&1)
        {
            cout<<ksm(2,n)<<endl;
        }
        else 
        {
            //ll ans=
           cout<<ksm(2,n-1)%mod<<endl;
        }
    }
    return 0;
}

E.小红开灯(四)

思路:每次只能改变相邻位置的灯的状态,无非开灯数就加2或者不变,所以奇数必定无解。如何偶数情况?发现00可以直接转换为00,而10可以转换为01,这个相当于把0往左移动了,所以先处理每一行,从右到左把0移动到最左段,此时要么有个0,要么没有0。随后再从上到下对第一列进行刚刚类似的操作即可得出答案。

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<cstring>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#include<bitset>
#define ll                           long long 
// #define lowbit(x) (x & -x)
//#define endl "\n"//                           交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)//快速幂
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
ll gcd(ll x, ll y)
{
    if (y == 0)
        return x;
    else
        return gcd(y, x % y);
}
ll lcm(ll x, ll y)
{
    x /= gcd(x, y);
    return y * x;
}
// inline ll read()//快读
// {
//     register ll x = 0, f = 1;
//     char c = getchar();
//     while (c < '0' || c>'9')
//     {
//         if (c == '-') f = -1;
//         c = getchar();
//     }
//     while (c >= '0' && c <= '9')
//     {
//         x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速
//         c = getchar();
//     }
//     return x * f;
// }
struct ss
{
    ll v, id;
    friend bool operator<(const ss& a, const ss& b)
    {
        return a.v < b.v;
    };
};
void fio()//加速流
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
ll e1[8] = { 0,1,0,-1,1,1,-1,-1 };
ll e2[8] = { 1,0,-1,0,1,-1,-1,1 };//前面四个为上下左右,后面四个为角落
int main()
{
    fio();
    ll t;
     t=1;
   // cin >> t;
    while (t--)
    {
        ll n,m;
        cin>>n>>m;
        string f[n+5];
        ll cnt=0;
        for(ll i=1;i<=n;i++)
        {
                cin>>f[i];
                f[i]='0'+f[i];
                for(ll j=1;j<=m;j++)
                {
                    cnt+=(f[i][j]=='0');
                }
        }
        if(cnt&1)cout<<-1<<endl;
        else if(cnt==0)cout<<0<<endl;
        else 
        {
            vector<pair<ll,ll>>ans1,ans2;
            ll cnt=0;
            for(ll i=1;i<=n;i++)
            {
                cnt=0;
                for(ll j=m;j>=1;j--)
                {
                    if(f[i][j]=='0')
                    {
                        if(cnt)cnt=0,f[i][j]='1',f[i][j+1]='1',ans1.push_back({i,j}),ans2.push_back({i,j+1});
                        else cnt++;
                    }
                    else if(f[i][j]=='1')
                    {
                        if(cnt)f[i][j]='0',f[i][j+1]='1',ans1.push_back({i,j}),ans2.push_back({i,j+1});
                        else cnt=0;
                    }
                }
            }
            cnt=0;
            for(ll i=1;i<=n;i++)
            {
                if(f[i][1]=='0')
                {
                    if(cnt)cnt=0,f[i][1]=f[i-1][1]='1',ans1.push_back({i,1}),ans2.push_back({i-1,1});
                    else cnt++;
                }
                else if(f[i][1]=='1')
                {
                    if(cnt)f[i][1]='0',f[i-1][1]='1',ans1.push_back({i,1}),ans2.push_back({i-1,1});
                    else cnt=0;
                }
            }
            cout<<ans1.size()<<endl;
            for(ll i=0;i<ans1.size();i++)
            {
                cout<<ans1[i].first<<" "<<ans1[i].second<<" "<<ans2[i].first<<" "<<ans2[i].second<<endl;
            }
        }
    }
    return 0;
}

F.小红开灯(五,easy)

这道题是贪心题,一开始想dp去了,没看样例,有点惭愧。发现对于一个树如果其直径为2或者3都只要一次操作,所以直接dfs,然后回溯的时候看下最大长度是否为3,如果为3,再加一次答案,否则把最大深度进行回溯。注意如果回溯到根时,最大长度如果为2也是要进行一次操作的,至此答案得出。

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<cstring>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#include<bitset>
#define ll                           long long 
// #define lowbit(x) (x & -x)
//#define endl "\n"//                           交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)//快速幂
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
ll gcd(ll x, ll y)
{
    if (y == 0)
        return x;
    else
        return gcd(y, x % y);
}
ll lcm(ll x, ll y)
{
    x /= gcd(x, y);
    return y * x;
}
// inline ll read()//快读
// {
//     register ll x = 0, f = 1;
//     char c = getchar();
//     while (c < '0' || c>'9')
//     {
//         if (c == '-') f = -1;
//         c = getchar();
//     }
//     while (c >= '0' && c <= '9')
//     {
//         x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速
//         c = getchar();
//     }
//     return x * f;
// }
struct ss
{
    ll v, id;
    friend bool operator<(const ss& a, const ss& b)
    {
        return a.v < b.v;
    };
};
void fio()//加速流
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
ll e1[8] = { 0,1,0,-1,1,1,-1,-1 };
ll e2[8] = { 1,0,-1,0,1,-1,-1,1 };//前面四个为上下左右,后面四个为角落
vector<ll>g[100000+ 5];
int main()
{
    fio();
    ll t;
    t = 1;
    // cin >> t;
    while (t--)
    {
        ll n;
        cin >> n;
        vector<vector<ll>>dp(n + 5, vector<ll>(2, 0));
        for (ll i = 1; i < n; i++)
        {
            ll l, r;
            cin >> l >> r;
            g[l].push_back(r);
            g[r].push_back(l);
        }
        //0关闭, 1开
        ll ans = 0;
        vector<bool>vis(n + 5);
        function<ll(ll, ll, ll)>dfs = [&](ll x, ll f, ll sd)
            {
                ll ok = 0;
                ll z;
                ll cn2=0,cn3=0;
                vector<ll>k;
                ll u=0;
                for (auto j : g[x])
                {
                    if (j == f)continue;
                    else z=dfs(j,x,sd+1);
                    if(z-sd+1==2)cn2++;
                    else if(z-sd+1==3)cn3++;
                    u=max(u,z);
                    ok = 1;
                }
                if(ok==0)return sd;
                if(x==1)
                {
                    if(cn3>0)ans+=cn3;
                    else if(cn2>0)ans++;
                    return (ll)99;
                }
                else if(cn3==0)
                {
                    return u;
                }
                else 
                {
                    ans+=cn3;
                    return sd-1;
                }
            };
        ll d = dfs(1, 0, 1);
        cout <<  ans << endl;
        // cout<<min(dp[1][0],dp[1][1])<<endl;
    }
    return 0;
}

G.小红开灯(五,hard)

思路:F写出来之后,这道题就好写了。
还是按照F的思路想,但是注意下,我们可以开个数组去记录下此时距离这个结点最远的结点。如此如果当深度差为3时,先把当前结点,和深度差值为3的路上的儿子进行一次连接,后续把其他差值为3的路上的儿子和用数组记录其对应的结点进行一次连接。此时传递一个无用答案即可(记得做个标记,后续算答案时直接跳过它)。当此时结点为根结点时,需要特判深度差为3的结点为0且深度差为2的结点>0的情况。这时随便连一个深度差为2的结点即可。如果不需要进行操作,更新下此时结点的数组,然后传递最大深度和当前结点即可。具体看看我代码吧

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<cstring>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#include<bitset>
#define ll                           long long 
// #define lowbit(x) (x & -x)
//#define endl "\n"//                           交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)//快速幂
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
ll gcd(ll x, ll y)
{
    if (y == 0)
        return x;
    else
        return gcd(y, x % y);
}
ll lcm(ll x, ll y)
{
    x /= gcd(x, y);
    return y * x;
}
// inline ll read()//快读
// {
//     register ll x = 0, f = 1;
//     char c = getchar();
//     while (c < '0' || c>'9')
//     {
//         if (c == '-') f = -1;
//         c = getchar();
//     }
//     while (c >= '0' && c <= '9')
//     {
//         x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速
//         c = getchar();
//     }
//     return x * f;
// }
struct ss
{
    ll v, id;
    friend bool operator<(const ss& a, const ss& b)
    {
        return a.v < b.v;
    };
};
void fio()//加速流
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
ll e1[8] = { 0,1,0,-1,1,1,-1,-1 };
ll e2[8] = { 1,0,-1,0,1,-1,-1,1 };//前面四个为上下左右,后面四个为角落
vector<ll>g[100000+ 5];
int main()
{
    fio();
    ll t;
    t = 1;
    // cin >> t;
    while (t--)
    {
        ll n;
        cin >> n;
        vector<vector<ll>>dp(n + 5, vector<ll>(2, 0));
        for (ll i = 1; i < n; i++)
        {
            ll l, r;
            cin >> l >> r;
            g[l].push_back(r);
            g[r].push_back(l);
        }
        //0关闭, 1开
        //ll ans = 0;
        vector<ll>vis(n + 5);
        vector<pair<ll,ll>>ans;
        function<pair<ll,ll>(ll, ll, ll)>dfs = [&](ll x, ll f, ll sd)
        {
            pair<ll,ll>z;
            vector<pair<ll,ll>>k2,k3;
            ll ok=0;
            for(auto j:g[x])
            {
                if(j==f)continue;
                else z=dfs(j,x,sd+1);
                if(z.first==-1)continue;
                if(z.first-sd+1==2)k2.push_back(z);
                else if(z.first-sd+1==3)k3.push_back(z);
                ok=1;
            }
            if(ok==0)
            {
                z={sd,x};
                vis[x]=x;
                return z;
            }
            if(k3.size()>0)
            {
                for(ll j=0;j<k3.size();j++)
                {
                    if(j==0)
                    {
                        ans.push_back({x,k3[j].second});
                    }
                    else ans.push_back({k3[j].second,vis[k3[j].second]});
                }
                z={-1,1};
                return z;
            }
            else if(k2.size()>0&&x==1)
            {
                ans.push_back({x,k2[0].second});
                z={-1,-1};
                return z;
            }
            else if(k2.size()==0) 
            {
                z={sd,x};
                vis[x]=x;
                return z;
            }
            else 
            {
                vis[x]=k2[0].second;
                z={k2[0].first,x};
                return z;
            }
        };
        pair<ll,ll> d = dfs(1, 0, 1);
        cout<<ans.size()<<endl;
        for(auto &[x,y]:ans)cout<<x<<" "<<y<<endl;
    }
    return 0;
}
posted @ 2025-04-13 21:45  长皆  阅读(123)  评论(0)    收藏  举报