省赛复习 二分答案+思维+图论

Posted 钟钟终

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了省赛复习 二分答案+思维+图论相关的知识,希望对你有一定的参考价值。

D. Toss a Coin to Your Graph…

解析在代码里,医保标准的二分答案题。
两个关键点:
1.在满足权值小于等于X时,搜索跑到循环里,满足题意要及时跳出;
2.记录走过的路径长,若是大于等于k,满足题意。

#include<bits/stdc++.h>
#define endl '\\n'
#define ll long long
using namespace std;
const int N=2e5+5;
int n,m,a[N],vis[N],cur[N];
ll k;
vector<int>g[N];
bool dfs(int i,int x) //判断在图中能否遍历k次

    if(cur[i])
        return 0;
    vis[i]=1;
    int res=0;
    for(int v:g[i])
    
        if(a[v]<=x)
        
            if(vis[v]) return 1;   //走入循环
            if(dfs(v,x)) return 1; //深搜判断能否进入循环
            res=max(res,cur[v]);   //记录经过的最大点数
        
    
    vis[i]=0;
    cur[i]=res+1;
    return 0;

bool check(int x)  //保证最大值为x

    for(int i=1;i<=n;i++)
        if(!cur[i]&&a[i]<=x)
    
        if(dfs(i,x))  //从这个点开始深搜小于x的点
            return 1;
        if(cur[i]>=k) //如果经过点数大于等于k,则满足
            return 1;
    
    return 0;

int main()

    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<=m;i++)
    
        int u,v;cin>>u>>v;
        g[u].push_back(v);
    
    int l=0,r=1e9,mid,ans=-1;
    while(l<=r)
    
        mid=l+r>>1;
        for(int i=1;i<=n;i++)
            vis[i]=cur[i]=0;
        if(check(mid)) //可以走k步,且最大值不超过mid
            r=mid-1,ans=mid;
        else
            l=mid+1;
    
    cout<<ans<<endl;
    return 0;


E. Replace With the Previous, Minimize

#include <bits/stdc++.h>

using namespace std;
const int N=2e5+5;
char s[N];
int n,k,a[N];
map<char,int>mp;
int main()

    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;cin>>t;
    while(t--)
    
        cin>>n>>k;
        int ans=0;
        mp.clear();
        cin>>(s+1);
        for(int i=1;i<=n;i++)
        
            while(s[i]>'a')
            
                if(mp[s[i]])
                    s[i]--;
                else if(k)
                    mp[s[i]]=1,k--,s[i]--;
                else break;
            
        
        for(int i=1;i<=n;i++)
            cout<<s[i];
        cout<<endl;
    
    return 0;


F. Vlad and Unfinished Business

#include <bits/stdc++.h>
#define endl '\\n'
#define ll long long
#define pb push_back
using namespace std;
const int N=2e5+5;
int n,k,x,y,a[N],fa[N];
bool vis[N];
vector<int>g[N];
void dfs(int u,int pre)

    fa[u]=pre;
    for(auto v:g[u])
        if(v!=pre)
            dfs(v,u);

int main()

    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;cin>>t;
    while(t--)
    
        cin>>n>>k;
        cin>>x>>y;
        for(int i=1;i<=n;i++)
        
            g[i].clear();
            vis[i]=0;fa[i]=0;a[i]=0;
        
        for(int i=1;i<=k;i++)
            cin>>a[i];
        for(int i=1;i<=n-1;i++)
        
            int u,v;cin>>u>>v;
            g[u].pb(v);g[v].pb(u);
        
        dfs(x,0);
        int ans=0;
        while(y!=x)
            ans++,vis[y]=1,y=fa[y];
        vis[x]=1;
        for(int i=1;i<=k;i++)
        
            int p=a[i];
            while(vis[p]==0)
                ans+=2,vis[p]=1,p=fa[p];
        
        cout<<ans<<endl;
    
    return 0;


以上是关于省赛复习 二分答案+思维+图论的主要内容,如果未能解决你的问题,请参考以下文章

图论题解求有向无环图 互不到达的最大点集的大小

2020.02.05总结

CF1364D Ehab‘s Last Corollary(思维,环,二分图,构造)

CF1364D Ehab‘s Last Corollary(思维,环,二分图,构造)

GDCPC 2017 省赛小结

Codeforces LATOKEN Round 1 (Div. 1 + Div. 2) D. Lost Tree(交互,二分/图,思维)