牛客网NOIP赛前集训营 提高组 第5场 T2 旅游

【题解】

  我们可以发现不在最小生成树上的边一定不能多次经过,因为一条不在最小生成树上的边(u,v)的边权比最小生成树上(u,v)之间的路径更长,选择不在最小生成树上的边一定不划算。

  我们还需要确定最小生成树上哪些边需要经过两次。我们发现如果某个点当前的度为奇数,这个点到它的父亲的边要经过两次,所以我们在它和它父亲之间多连上一条边(即把他们的度都加1).

  这样一次dfs我们就可以从下往上确定出需要经过两次的边。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define LL long long
 5 #define N 500010
 6 #define rg register
 7 using namespace std;
 8 const int Mod=998244353;
 9 int n,m,tot,cnt,last[N],in[N],fa[N];
10 LL ans,Pow[N];
11 struct edge{int to,pre,dis;}e[N<<1];
12 struct rec{int u,v;}r[N];
13 inline int read(){
14     int k=0,f=1; char c=getchar();
15     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
16     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
17     return k*f;
18 }
19 void dfs(int x,int f,int eg){
20     for(rg int i=last[x],to;i;i=e[i].pre)if((to=e[i].to)!=f) dfs(to,x,i);
21     if((in[x]&1)&&x!=1)    ans=(ans+Pow[e[eg].dis])%Mod,in[f]++;
22 }
23 int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
24 int main(){
25     n=read(); m=read(); Pow[0]=1;
26     for(rg int i=1;i<=m;i++){
27         Pow[i]=(Pow[i-1]<<1)%Mod; ans=(ans+Pow[i])%Mod;
28         in[r[i].u=read()]++; in[r[i].v=read()]++;
29     }
30     for(rg int i=1;i<=n;i++) fa[i]=i;
31     for(rg int i=1;i<=m;i++){
32         int u=r[i].u,v=r[i].v;
33         if(find(u)!=find(v)){
34             e[++tot]=(edge){u,last[v],i}; last[v]=tot;
35             e[++tot]=(edge){v,last[u],i}; last[u]=tot;
36             fa[find(u)]=find(v);
37             cnt++; if(cnt==n-1) break;
38         }
39     }
40     dfs(1,0,0);
41     printf("%lld\n",ans);
42     return 0;
43 }

 

转载于:https://www.cnblogs.com/DriverLao/p/9795786.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。在编写C程序时,需要注意变量的声明和定义、指针的使用、内存的分配与释放等问题。C语言中常用的数据结构包括: 1. 数:一种存储同类型数据的结构,可以进行索引访问和修改。 2. 链表:一种存储不同类型数据的结构,每个节点包含数据和指向下一个节点的指针。 3. 栈:一种后进先出(LIFO)的数据结构,可以通过压入(push)和弹出(pop)操作进行数据的存储和取出。 4. 队列:一种先进先出(FIFO)的数据结构,可以通过入队(enqueue)和出队(dequeue)操作进行数据的存储和取出。 5. 树:一种存储具有父子关系的数据结构,可以通过中序遍历、前序遍历和后序遍历等方式进行数据的访问和修改。 6. 图:一种存储具有节点和边关系的数据结构,可以通过广度优先搜索、深度优先搜索等方式进行数据的访问和修改。 这些数据结构在C语言中都有相应的实现方式,可以应用于各种不同的景。C语言中的各种数据结构都有其优缺点,下面列举一些常见的数据结构的优缺点: 数: 优点:访问和修改元素的速度非常快,适用于需要频繁读取和修改数据的合。 缺点:数的长度是固定的,不适合存储大小不固定的动态数据,另外数在内存中是连续分配的,当数较大时可能会导致内存碎片化。 链表: 优点:可以方便地插入和删除元素,适用于需要频繁插入和删除数据的合。 缺点:访问和修改元素的速度相对较慢,因为需要遍历链表找到指定的节点。 栈: 优点:后进先出(LIFO)的特性使得栈在处理递归和括号匹配等问题时非常方便。 缺点:栈的空间有限,当数据量较大时可能会导致栈溢出。 队列: 优点:先进先出(FIFO)的特性使得

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值