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;
}


posted @ 2022-05-15 22:01  wtz2333  阅读(93)  评论(0)    收藏  举报