Atcoder ABC251
Atcoder ABC251 A—F
第一次abc6个题,非常舒服(其实是五个,由于倒着做最后差一分钟c没有交上,不过从排名上看过不过C影响不大。看没有官方题解,就来写一发。😊
A
简单模拟,略
B
简单模拟,由于用来map被卡了常数,被迫加了个剪枝。😅
C
简单模拟,用一下map或set就可以。
D
开场做的D,被卡了10分钟,10分钟后就大概知道该怎么做了。但把总个数一开始敲错了,被罚了一发。
题解:
考虑到只能有300个数去表示 \(1e6\) 级别的数所以我们把数拆成100进制来表示,这样就可以只用298个数就可以了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int w;
void solve(){
cin >> w;
cout<<298<<"\n";
int tmp = 0;
for(int i = 1;i < 100;i ++,tmp ++)cout<<i<<" ";
for(int i = 100;i < 10000;i += 100,tmp++)cout<<i<<" ";
for(int i = 10000;i <= 1000000;i += 10000,tmp++)cout<<i<<" ";
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
solve();
return 0;
}
E
简单dp,个人觉得E比D简单一些,至少读完题思路就有了。
题解:
由于是环,所以要在1处断一下,对1的位置进行一下2种情况的讨论。dp的状态为到 \(i\) 这个位置这个位置被选或不选的满足要求的最小花费。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 7;
int n;
int a[maxn];
ll dp[maxn][2];
ll f[maxn][2];
void solve(){
cin >> n;
for(int i = 1;i <= n;i ++)cin >> a[i];
a[0] = a[n];
dp[0][1] = a[n];
for(int i = 1;i <= n;i ++){
dp[i][1] = min(dp[i - 1][1],dp[i - 1][0]) + a[i];
if(i == 1)dp[i][1] = 1ll << 60;
dp[i][0] = dp[i - 1][1];
}
for(int i = 1;i <= n;i ++){
f[i][1] = min(f[i - 1][1],f[i - 1][0]) + a[i];
if(i == 1)f[i][0] = 1ll << 60;
else f[i][0] = f[i - 1][1];
}
cout<<min(min(dp[n - 1][1],min(dp[n - 1][0],f[n][1])),f[n][0])<<"\n";
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
solve();
return 0;
}
F
乍一看,不知道这个题在说啥。
题解:想一想,可以发现 \(T_{1}\) 只要按照dfs序就是满足要求的。证明就随便口胡一下:考虑对任意一条不在dfs树上的边,根据我们学tarjan的知识,我们可以知道这个一定是返祖边,所以dfs序就是对的。
再看\(T_{2}\) ,可以发现我们希望这个点到1的距离最短就是满足要求的,那么就是最短路树,对于边权为1的图就是bfs序。我比较偷懒就直接拉了个最短路树的板子了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 7;
int n,m,l;
int pre[maxn << 1],last[maxn],other[maxn << 1],len[maxn << 1];
int dis[maxn],from[maxn];
bool vis[maxn];
struct node {
int id,d;
bool operator < (const node &b) const {return d>b.d;}
};
void add(int x,int y,int z){
l ++;
pre[l] = last[x];
last[x] = l;
other[l] = y;
len[l] = z;
}
void dijkstra(int s)
{
for(int i = 0;i <= n;i ++) dis[i] = 847483647,vis[i]=0,from[i]=0;
priority_queue<node> q;
dis[s] = 0;
q.push((node){s,0});
while(!q.empty())
{
node cur = q.top();q.pop();
int u = cur.id;
if(vis[u]) continue;
vis[u] = 1;
for(int p = last[u];p;p = pre[p])
{
int v = other[p];
if(dis[v]>dis[u]+len[p])
{
dis[v] = dis[u]+len[p];
q.push((node){v,dis[v]});
from[v] = u;
}
}
}
}
void dfs(int x){
vis[x] = 1;
for(int p = last[x];p;p = pre[p]){
int v = other[p];
if(vis[v])continue;
from[v] = x;
dfs(v);
}
}
void solve(){
cin >> n >> m;
for(int i = 1;i <= m;i ++){
int a,b;
cin >> a >> b;
add(a,b,1);add(b,a,1);
}
dfs(1);
for(int i = 2;i <= n;i ++)cout<<i<<" "<<from[i]<<"\n";
dijkstra(1);
for(int i = 2;i <= n;i ++)cout<<i<<" "<<from[i]<<"\n";
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
solve();
return 0;
}

浙公网安备 33010602011771号