AtCoder Grand Contest 025

链接

D. Choosing Points

考虑如果只有 D,可以由于发现 x2+y2=D 的所有解中 x+y 的奇偶性相同,所以连成的图是一张二分图。

二分图的最大独立子集显然大于等于点数一半。

那么两张二分图的最大独立子集显然大于等于点数的 14。直接枚举是哪一边的点集即可。复杂度 O(n2)

E. Walking on a Tree

官网题解做法:

考虑每次取一个叶子,如果这个叶子上只有一条路径,那么这个叶子可以不用管,路径的起点顺延到它的父亲。否则考虑任意取两条路径 ua,ub,考虑他们的交 uc,显然交部分就是 2,剩余部分等价于一条 ab 的路径。

最后返回去构造初始路径。

神仙做法

考虑如果存在当前只剩下一条路径的点,并且只被单向经过过一次,那么这条路径必须以另一方向经过。

否则说明所有路径都至少有两条路径,随便构造即可。

复杂度 O(n2)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define N 4010
#define fi first
#define se second
#define MP make_pair
using namespace std;
typedef pair<int,int> P;
int x[N],y[N];
vector<P>g[N];
int dep[N],fa[N],rf[N];
void dfs(int u,int p)
{
    fa[u]=p;dep[u]=dep[p]+1;
    for(auto &[v,w]:g[u]) if(v!=p) rf[v]=w,dfs(v,u);
}
void get(int x,int y,vector<int>&w)
{
    for(;dep[x]>dep[y];x=fa[x]) w.push_back(rf[x]^1);
    for(;dep[y]>dep[x];y=fa[y]) w.push_back(rf[y]);
    for(;x!=y;x=fa[x],y=fa[y]) w.push_back(rf[x]^1),w.push_back(rf[y]);
}
vector<int>p[N],id[N];int deg[N],vis[N],op[N];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1,u,v;i<n;i++) scanf("%d%d",&u,&v),g[u].push_back(MP(v,2*i)),g[v].push_back(MP(u,2*i+1));
    dfs(1,0);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x[i],&y[i]);
        get(x[i],y[i],p[i]);
        for(int v:p[i]) id[v/2].push_back(i),deg[v/2]++/*,printf("- %d ",v);puts("")*/;
    }
    long long ans=0;
    for(int i=1;i<n;i++) ans+=min(2,deg[i]);
    printf("%lld\n",ans);
    while(true)
    {
        int u=0,w=0;
        for(int i=1;i<n;i++) if(deg[i]==1 && op[i*2]!=op[i*2+1]){w=i;break;}
        if(!w) for(int i=1;i<n;i++) if(deg[i]>=2){w=i;break;}
        if(!w) break;
        for(int v:id[w]) if(!vis[v]){u=v;break;}
        vis[u]=true;
        for(int v:p[u]) if(v/2==w)
        {
            if(op[v]) swap(x[u],y[u]),for_each(p[u].begin(),p[u].end(),[&](int &x){x^=1;});
            for_each(p[u].begin(),p[u].end(),[&](int &x){deg[x/2]--,op[x]=true;});
        }
    }
    for(int i=1;i<=m;i++) printf("%d %d\n",x[i],y[i]);
    return 0;
}
posted @   Flying2018  阅读(8)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示