C. Cycle Graph?

题意

给你一个 \(N\) 个顶点 \(M\) 条边的简单(无重边、自环)无向图,第 \(i\) 条边连接节点 \(A_i\) 和 \(B_i\),判断这个图是不是一个环。

思路

首先一个图是环,要满足点数等于边数,即 \(N=M\);

其次,这个图必须连通,可以通过 \(\text{DFS}\) 或 \(\text{BFS}\) 搜索判断是否连通(从任意一点开始搜,结束后检查是否每个点都已到达过);

最后,每个点的度数(所连接的顶点数)必须为 \(2\)。

可以证明,只要满足上述三个条件,这个图一定是一个环。

C++ 代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=200005;
int n,m;
int deg[maxn];
vector<int> g[maxn];
bool used[maxn];
void dfs(int v){
used[v]=true;
for(int x:g[v]){
if(!used[x]){
dfs(x);
}
}
}
int main(){
cin>>n>>m;
if(n!=m){
cout<<"No\n";
return 0;
}
for(int i=1;i<=m;i++){
int u,v; cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1);
for(int i=1;i<=n;i++){
if(!used[i]||g[i].size()!=2){
cout<<"No\n";
return 0;
}
}
cout<<"Yes\n";
return 0;
}

D. Goin' to the Zoo

题意

\(N\) 个动物园,动物园 \(i\) 入场费为 \(C_i\)。\(M\) 种动物,第 \(j\) 种动物可以在共 \(K_j\) 个动物园看到,分别为动物园 \(A_{j,1},A_{j,2},\ ...,A_{j,K_j}\)。

要看每种动物至少两次,至少花多少钱。

注:只要花一次 \(C_i\),就可以进入动物园 \(i\) 一次,就可以看里面的每个动物一次;若花两次,则可进入两次,看里面的动物两次

思路

由于 \(N \le 10,M\le 100\),可以想到用状态压缩(不是dp)枚举。

状态压缩,就是把状态压缩到一个数字里

大致思路如下:

以 \(140\) 为例,三进制数为 \(12012\):

这样,\(1\sim 3^N\) 的每个数字都有了实际含义

只要枚举 \(1\sim3^N\) 的每个数,判断这样参观动物园能否达成“每种动物至少看两次”的目标,若可以,则记录答案,取最小值。

时间复杂度 \(O(NM·3^N )\)

C++ 代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int inf=3e18;
const int maxn=1000005;
int c[maxn];
int k[105];
int v[105][105];
int mask[105];
int n,m;
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>c[i];
}
for(int i=1;i<=m;i++){
cin>>k[i];
for(int j=0;j<k[i];j++){
cin>>v[i][j];
}
}
int ans=inf;
for(int msk=0;msk<pow(3ll,n);msk++){
memset(mask,0,sizeof(mask));//mask为当前数字所对应的三进制数
int num=0;//num为花费
int p=msk;
for(int i=1;i<=n;i++){
num+=(p%3)*c[i];
for(int j=1;j<=m;j++){
for(int a=0;a<k[j];a++){
if(v[j][a]==i) mask[j]+=p%3;
}
}
p/=3;
}
bool flag=true;
for(int j=1;j<=m;j++){
if(mask[j]<2) flag=false;
}
if(flag) ans=min(ans,num);
}
cout<<ans<<endl;
return 0;
}

E. Bowls and Beans

题意

\(N\) 个碗排成一排,编号为 \(0\sim N-1\),碗 \(i\) 中有 \(A_i\) 个豆子,上面写着一个数字 \(C_i\)。

每次操作可以将碗 \(i\) 里的豆子可以放到之前 \(i-C_i \sim i-1\) 中的任意碗里,并且可以任意分配每个碗里放几颗。

最初碗 \(0\) 中没有豆子,问:将所有豆子都移到碗 \(0\) 中,最少需要多少步。

思路

贪心好像也可以,但是我不会!!

\(N \le 2000\),考虑 \(O(n^2)\) 动态规划。

动态规划基本三步:

  1. 设计 \(\text{DP}\) 状态:

​ 定义 \(f_i\) 表示将编号 \(\ge i\) 的所有碗中的豆子全部移到碗 \(i\) 中的最小步骤;

  1. 初始化:

​ 设最后一个有豆子的碗为 \(p\),则对于 \(i=p\sim n-1\),\(f_i=0\)(不需要操作),其余初始 \(f_i=\infty\);

  1. 转移顺序及转移方程:

    顺序:由于每个碗里的豆子只能往前移,为避免转移产生影响后续计算,应从后往前转移;

    满足以下条件时,\(f_i=\min(f_i,f_j+1)\):

    • 条件1:\(j>i\);

    • 条件2:碗 \(j\) 的豆子可以移到碗 \(i\) 中,即\(j-i \le C_j\);

    • 条件3:若 \(i-j\ge2\),\(i+1\) 到 \(j-1\) 之间的任何一个碗都没有豆子(否则不可能一步就完成 \(j \rightarrow i\) 的操作)。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int inf=3e18;
const int maxn=2005;
int n;
int c[maxn],f[maxn];
bool a[maxn];
signed main(){
cin>>n;
for(int i=1;i<n;i++) cin>>c[i];
for(int i=1;i<n;i++) cin>>a[i]; //初始化
for(int i=0;i<n;i++) f[i]=inf;
int pos;
for(int i=n-1;i>=0;i--){
f[i]=0;
if(a[i]){
pos=i-1;
break;
}
} //转移
for(int i=pos;i>=0;i--){//为了避免产生后效性,从后往前遍历
for(int j=i+1;j<n;j++){//为了满足条件1,j=i+1开始
if(j-i<=c[j]) f[i]=min(f[i],f[j]+1);//为了满足条件2
if(a[j]) break;//为了满足条件3,只要遇到了有豆子的碗就退出
}
}
cout<<f[0]<<endl;
return 0;
}

G. Specified Range Sums

题意

有三个长度为 \(M\) 的序列 \(L,R,S\),你要判断是否存在一个长度为 \(N\) 的 正整数 序列 \(A\),满足以 \(\sum_{j=L_i}^{R_i} A_j=S_i\)。

若存在,找到最小的 $\sum_{j=1}^N A_j $;否则,输出 -1

思路

首先,我们考虑将求和转换为前缀和,即定义 \(C_i=\sum_{j=1}^iA_j\),则\(C_{R_i}-C_{L_i-1}=S_i\)。

建立有向图,顶点编号为 \(0 \sim n\),这样连边:\((L_i-1,R_i)=S_i\),\((R_i,L_i-1)=-S_i\)。另外,由于是正整数序列,所以 \((i+1,i)=-1\)。

我们需要计算 \(n \rightarrow 0\) 的最短路,答案即为这个值的相反数。

注意:无解时图中有负环,所以 \(\text{Dijkstra}\) 不可以。考虑可以处理负环的 \(\text{Bellman-Ford}\) 算法(不会没关系,下面讲):

与图上动态规划相似,定义 \(dis_i\) 表示 从 \(n\) 到 \(i\) 的最短路,\(dis_n=0\),其余为 \(\infty\)。

共进行 \(N\) 次操作,每次操作如下:

  • 对于每一条有向边 \((u,v)=w\),\(dis_v=\min(dis_v,dis_u+w)\),共 \(M\) 条边。

复杂度为 \(O(NM)\),通常把上述操作称作 松弛(relax)

在这 \(N\) 次松弛之后,再执行第 \(N+1\) 次操作,若还可以继续执行松弛操作,就说明图中存在负环,无解,输出 \(-1\)。

最终答案即为 \(-dis_0\)。

C++ 代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int inf=3e18;
const int maxn=4005;
int n,m;
struct Node{
int u,v,w;
};
vector<Node> v;
int dis[maxn];
signed main(){
cin>>n>>m; //建图 连边
for(int i=1;i<=m;i++){
int l,r,s;
cin>>l>>r>>s;
v.pb({l-1,r,s});
v.pb({r,l-1,-s});
}
for(int i=0;i<n;i++) v.pb({i+1,i,-1}); //初始化
for(int i=1;i<=n;i++) dis[i]=inf;
dis[n]=0; //Bellman-Ford计算最短路 直接将第N+1次操作放入循环中
for(int i=1;i<=n+1;i++){
for(Node e:v){
if(dis[e.v]>dis[e.u]+e.w){
if(i==n+1){//若已经执行完n+1次松弛还可以继续执行,则无解
cout<<-1<<endl;
return 0l
}
dis[e.v]=dis[e.u]+e.w;
}
}
}
cout<<-dis[0]<<endl;
return 0;
}

AtCoder Beginner Contest 404 C-G(无F)题解的更多相关文章

  1. [题解] Atcoder Beginner Contest ABC 270 G Ex 题解

    点我看题 G - Sequence in mod P 稍微观察一下就会发现,进行x次操作后的结果是\(A^xS+(1+\cdots +A^{x-1})B\).如果没有右边那一坨关于B的东西,那我们要求 ...

  2. AtCoder Beginner Contest 137 F

    AtCoder Beginner Contest 137 F 数论鬼题(虽然不算特别数论) 希望你在浏览这篇题解前已经知道了费马小定理 利用用费马小定理构造函数\(g(x)=(x-i)^{P-1}\) ...

  3. AtCoder Beginner Contest 238 A - F 题解

    AtCoder Beginner Contest 238 \(A - F\) 题解 A - Exponential or Quadratic 题意 判断 \(2^n > n^2\)是否成立? S ...

  4. AtCoder Beginner Contest 272 - G - Yet Another mod M

    随机 + 数论 题意 Submission #35524126 - AtCoder Beginner Contest 272 给一个长度为 \(n\;(1<=n<=5000)\) 的数组 ...

  5. AtCoder Beginner Contest 184 题解

    AtCoder Beginner Contest 184 题解 目录 AtCoder Beginner Contest 184 题解 A - Determinant B - Quizzes C - S ...

  6. AtCoder Beginner Contest 136

    AtCoder Beginner Contest 136 题目链接 A - +-x 直接取\(max\)即可. Code #include <bits/stdc++.h> using na ...

  7. AtCoder Beginner Contest 154 题解

    人生第一场 AtCoder,纪念一下 话说年后的 AtCoder 比赛怎么这么少啊(大雾 AtCoder Beginner Contest 154 题解 A - Remaining Balls We ...

  8. AtCoder Beginner Contest 177 题解

    AtCoder Beginner Contest 177 题解 目录 AtCoder Beginner Contest 177 题解 A - Don't be late B - Substring C ...

  9. 题解 AtCoder Beginner Contest 168

    小兔的话 欢迎大家在评论区留言哦~ AtCoder Beginner Contest 168 A - ∴ (Therefore) B - ... (Triple Dots) C - : (Colon) ...

  10. KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解

    KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解 哦淦我已经菜到被ABC吊打了. A - Century 首先把当前年 ...

随机推荐

  1. WPF DevExpress GridColumn ComboBox 显示选择内容的 TooTip

    实现显示当前选择的ComboBox中项的ToolTip信息: 1. 设置 GridColumn 的 CellTemplate 为 ComboBoxEdit , 然后自定义他的 ItemContaine ...

  2. Google 助手安装

    转自:https://www.jianshu.com/p/6086ec29c173 今天这篇推送可能是很多人都需要的,因为它能帮助你无阻碍的访问Google.Google scholar.Gmail. ...

  3. 面试官最想听到的Vue和React区别

    前言 欧阳最近找工作面试时总是被问到两个问题:Vue和React的区别和从编译原理的角度来聊聊Vue的template和React的jsx.面试官问这些问题一般是想了解你对这两个框架的理解,所以这是一 ...

  4. ollama-deepseek 部署

    选择云资源 选用智星云 4090 高性能 1.57 一小时 windows操作系统 可以修改带宽来增加下载速度 使用mstsc远程登录 使用ollama https://ollama.com/ oll ...

  5. PERT 图表教程

    (翻译自: PERT Chart Tutorial) PERT 图表 是(程序评估和审查技术)的首字母缩写.PERT 图是一种项目管理工具,用于在项目中安排.组织和协调任务.它基本上是一种分析完成给定 ...

  6. 大数据之路Week08_day06 (Zookeeper初识)

    让我们来回顾一下我们在学习Hadoop中的HDFS的时候,肯定见过下面这样的两幅图: 这副图代表着什么呢?它介绍的是Hadoop集群的高可靠,也就是前面提过的HA,仔细观察一下这副图,我们发现有两个N ...

  7. 大数据之路Week08_day03 (Hive优化)

    Hive优化(下面的红色标记是十分重要的,大部分情况是需要开启的) 优化1:hive的抓取策略理论上来说,Hive中的所有sql都需要进行mapreduce,但是hive的抓取策略帮我们省略掉了这个过 ...

  8. springboot本地运行正常,打包jar包上传Linux服务器后报错,无法正常运行解决方法

    问题描述:springboot本地运行正常,打包jar包上传Linux服务器后报错,无法正常运行 说明:以下两种打包方式均在IDEA软件内完成,上传服务器使用宝塔面板管理 1.第一次打包方式: 设置完 ...

  9. deepseek:微信公众号网页授权能否获知是否关注公众号

    在微信公众号开发中,网页授权(OAuth2.0)可以获取用户的基本信息(如 openid.昵称.头像等),但默认情况下,网页授权无法直接获取用户是否关注公众号.这是因为网页授权的设计初衷是为了获取用户 ...

  10. CTF-CRYPTO-ECC(1)

    CTF-CRYPTO-ECC(1) 椭圆加密 1.简介 椭圆曲线密码学(Elliptic curve cryptography),简称 ECC,和RSA.ElGamel 算法等类似,是一种公开秘钥加密 ...