[CSP-S模拟测试]:Graph(图论+贪心)
Posted wzc521
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CSP-S模拟测试]:Graph(图论+贪心)相关的知识,希望对你有一定的参考价值。
题目描述
给定一张$n$个点$m$条边的无向图,每条边连接两个顶点,保证无重边自环,不保证连通你想在这张图上进行若干次旅游,每次旅游可以任选一个点$x$作为起点,再走到一个与 $x$直接有边相连的点$y$,再走到一个与$y$直接有边相连的点$z$并结束本次旅游
作为一个旅游爱好者,你不希望经过任意一条边超过一次,注意一条边不能即正向走一次又反向走一次,注意点可以经过多次,在满足此条件下,你希望进行尽可能多次的旅游,请计算出最多能进行的旅游次数并输出任意一种方案
输入格式
第$1$行两个正整数$n$与$m$,表示全图的点数与边数
下接$m$行,每行两个数字$u$与$v$表示一条边
输出格式
第$1$行一个整数$cnt$表示答案
下接$cnt$行,每行三个数字$x,y$与$z$,表示一次旅游的路线
如有多种旅行方案,任意输出一种即可
样例
样例输入:
4 5
1 2
3 2
2 4
3 4
4 1
样例输出:
2
4 1 2
4 3 2
数据范围与提示
对于前$20\\%$的数据,$n\\leqslant 10,m\\leqslant 20$
对于令$20\\%$的数据,$m=n−1$,并且图连通
对于令$10\\%$的数据,每个点的度数不超过$2$
对于$100\\%$的数据,$n\\leqslant 100,000,m\\leqslant 200,000$
题解
如果你做过下面这两道题的其中一道,这道题就会显得简单多了:
题不一样,但是思路是类似的。
对于树和链,我们显然是从叶子节点开始一定最优。
那么考虑一般情况,利用上面那两道题的思路(尤其是虎),也有点类似无修支配树,总之都是贪心……
时间复杂度:$\\Theta(n)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
struct recint nxt,to;e[400001];
struct nodeint x,y,z;;
int head[100001],cnt=1;
int n,m;
int depth[100001];
vector<node> ans;
void add(int x,int y)
e[++cnt].nxt=head[x];
e[cnt].to=y;
head[x]=cnt;
int dfs(int x)
int res=0;
for(int i=head[x];i;i=e[i].nxt)
if(!depth[e[i].to])
depth[e[i].to]=depth[x]+1;
int flag=dfs(e[i].to);
if(flag)ans.push_back((node)flag,e[i].to,x);
else
flag=e[i].to;
if(res)ans.push_back((node)flag,x,res);res=0;
else res=flag;
else
if(depth[e[i].to]>depth[x])
int flag=e[i].to;
if(flag)
if(res)ans.push_back((node)flag,x,res);res=0;
else res=flag;
return res;
int main()
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
int x,y;
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
for(int i=1;i<=n;i++)
if(!depth[i])
depth[i]=1;
dfs(i);
printf("%d\\n",ans.size());
for(int i=0;i<ans.size();i++)printf("%d %d %d\\n",ans[i].x,ans[i].y,ans[i].z);
return 0;
rp++
以上是关于[CSP-S模拟测试]:Graph(图论+贪心)的主要内容,如果未能解决你的问题,请参考以下文章