首页 > 其他分享 >Codeforces 图论题

Codeforces 图论题

时间:2024-02-22 21:01:54浏览次数:21  
标签:head int Codeforces st tail 论题 define size

CF243B Hydra

枚举点 \(u,v\),或者说枚举边。然后找出 \(u,v\) 分别所连的点。

有数组 \(st\),结点 \(x\) 仅与 \(u\) 相邻则 \(st[x]=1\),仅与 \(v\) 相邻则 \(st[x]=2\),与两个点都相邻则 \(st[x]=3\)。

用数组 \(rest\) 记录 \(st[x]=3\) 的所有 \(x\)。先优先选走至多 \(h\) 个 \(x|st[x]=1\),再选走至多 \(t\) 个 \(x|st[x]=2\)。如果还不够就动用 \(rest\) 里面的。这个贪心很显然。

\(h,t\) 很小,复杂度可以保证。注意清空 \(st\) 不能直接 memset

#include <bits/stdc++.h>
#define F first
#define S second
#define pii pair<int, int>
#define ll long long
#define rep(i, s, t) for(int i=s; i<=t; ++i)
#define debug(x) cout<<#x<<":"<<x<<endl;
const int N=100010;
using namespace std;

int n, m, h, t, st[N];
vector<int> g[N];
int rest[N], k;

int main()
{
    #ifdef Jerrywang
    freopen("in.txt", "r", stdin);
    #endif
    scanf("%d%d%d%d", &n, &m, &h, &t);
    rep(i, 1, m)
    {
        int u, v; scanf("%d%d", &u, &v);
        g[u].push_back(v);
        g[v].push_back(u);
    }
    rep(u, 1, n) for(int v:g[u])
    {
        if(g[u].size()<=h || g[v].size()<=t) continue;
        for(int x:g[u]) if(x!=v)
            st[x]=1;
        k=0;
        for(int x:g[v]) if(x!=u)
        {
            st[x]+=2;
            if(st[x]==3) rest[++k]=x;
        }
        vector<int> head, tail;
        for(int x:g[u]) if(x!=v && st[x]==1)
        {
            head.push_back(x);
            if(head.size()>=h) break;
        }
        for(int x:g[v]) if(x!=u && st[x]==2)
        {
            tail.push_back(x);
            if(tail.size()>=t) break;
        }
        while(head.size()<h && k)
            head.push_back(rest[k--]);
        while(tail.size()<t && k)
            tail.push_back(rest[k--]);
        if(head.size()>=h && tail.size()>=t)
        {
            puts("YES");
            printf("%d %d\n", u, v);
            for(int x:head) printf("%d ", x);
            puts("");
            for(int x:tail) printf("%d ", x);
            return 0;
        }
        for(int x:g[u]) st[x]=0;
        for(int x:g[v]) st[x]=0;
    }
    puts("NO");
    
    return 0;
}

CF237E Build String

比较简单的费用流。

对源字符串和字母建点。

对于目标字符串中的每个字符 \(c\),建边 \((c, t)\),容量为 \(1\),费用为 \(0\)。

然后考虑源字符串,计算费用。对于字符串 \(i\) 中的每个字符 \(c\),建边 \((i, c)\),容量为 \(1\),费用为 \(i\)。

最后考虑限制,限制字符串 \(i\) 最多取 \(x\) 个字符,相当于建边 \((s, i)\),容量为 \(x\),费用为 \(0\)。

#include <bits/stdc++.h>
#define F first
#define S second
#define pii pair<int, int>
#define ll long long
#define rep(i, s, t) for(int i=s; i<=t; ++i)
#define debug(x) cout<<#x<<":"<<x<<endl;
const int N=100010, inf=1e9;
using namespace std;

struct edge
{
    int v, c, w, n;
} e[N]; int hd[N], tot=1, n, m, s, t, siz;
void add(int u, int v, int c, int w)
{
    e[++tot]={v, c,  w, hd[u]}, hd[u]=tot;
    e[++tot]={u, 0, -w, hd[v]}, hd[v]=tot;
}
int d[N], in[N], f[N], pre[N];
bool spfa()
{
    rep(i, 1, t) d[i]=inf, in[i]=0;
    queue<int> q; q.push(s);
    d[s]=0, in[s]=1; f[s]=inf;
    while(q.size())
    {
        int u=q.front(); q.pop(); in[u]=0;
        for(int i=hd[u]; i; i=e[i].n)
        {
            int v=e[i].v, c=e[i].c, w=e[i].w;
            if(c && d[u]+w<d[v])
            {
                d[v]=d[u]+w;
                f[v]=min(f[u], c); pre[v]=i;
                if(!in[v]) in[v]=1, q.push(v);
            }
        }
    }
    return d[t]<inf;
}
int EK()
{
    int res=0, flow=0;
    while(spfa())
    {
        int u=t;
        while(u!=s)
        {
            int i=pre[u];
            e[i].c-=f[t], e[i^1].c+=f[t];
            u=e[i^1].v;
        }
        res+=f[t]*d[t], flow+=f[t];
    }
    if(flow<siz) res=-1;
    return res;
}
char a[N];
int main()
{
    #ifdef Jerrywang
    freopen("in.txt", "r", stdin);
    #endif
    scanf("%s%d", a+1, &n);
    s=n+26+1, t=s+1;
    siz=strlen(a+1); int x;
    rep(j, 1, siz)
    {
        x=a[j]-'a'+1;
        add(n+x, t, 1, 0);
    }
    rep(i, 1, n)
    {
        scanf("%s%d", a+1, &x);
        add(s, i, x, 0);
        m=strlen(a+1);
        rep(j, 1, m)
        {
            x=a[j]-'a'+1;
            add(i, n+x, 1, i);
        }
    }
    printf("%d", EK());
    
    return 0;
}

标签:head,int,Codeforces,st,tail,论题,define,size
From: https://www.cnblogs.com/jerrywang2009/p/18028166

相关文章

  • Codeforces 869D The Overdosing Ubiquity
    考虑树的\(\text{dfs}\)(根据当前节点\(u\)找到\(v\)满足存在\((u,v)\),然后走向\(v\)进入更深的搜索)为和能做到\(O(n)\)的复杂度。原因是没有环的情况,到每个点只有一条路径。回到这个题,有\(m\)条边导致到每个点可能有多条路径了。能发现其实还是能\(\text{dfs}\)......
  • Codeforces 1876F - Indefinite Clownfish
    首先注意到这样一个性质:既然两个序列的平均值相同,并且又形成公差\(\pm1\)的等差数列,就必然会存在一个元素\(x\)满足\(x\)在两个序列中都出现过(否则两个序列的值域区间不交,值域区间靠后的那个显然平均值比靠前的那个大)。那么我们枚举\(x\)在两个序列中出现的位置\(p\)和......
  • Codeforces Round 923 (Div. 3)
    A.MakeitWhite#include<bits/stdc++.h>usingnamespacestd;usingi32=int32_t;usingi64=longlong;usingi128=__int128;usingldb=longdouble;#defineinti64usingvi=vector<int>;usingpii=pair<int,int>;usingvii......
  • Codeforces Round 928 (Div. 4)
    CodeforcesRound928(Div.4)比赛链接A.VladandtheBestofFive思路就是统计字符A和字符B的个数,将个数多的那个输出出来Code#include<bits/stdc++.h>usingnamespacestd;#defineall(x)x.begin()+1,x.end()#defineintlonglongvoidsolve(){strings;......
  • Codeforces 1806E Tree Master
    考虑一个最基础的暴力,就是直接记忆化搜索暴力往上跳。但是能发现如果一层的节点数过多,状态数太多,就寄了。再考虑一个基础的暴力,就是直接跳。但是如果要跳的层数过多,就寄了。考虑结合一下,根号分治。对于一层内节点数\(\le\sqrt{n}\)的记录下每两个点间的答案。对于节点数......
  • Codeforces Round 928(Div. 4)
    Dashboard-CodeforcesRound928(Div.4)-Codeforces第一次参加CF,最后一道题连题都没读,下次不会就跳,菜是原罪A:找字符串中A,B数量,遍历一下最后比较即可B:判断是三角形还是正方形,题目表示除了正方形就是三角形,所以直接判断是不是正方形,用ans数组记录每一行1的个数,然后从大......
  • Codeforces Round 900 (Div. 3)
    题目A.只要k出现过就是YES#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=1e5+10;#defineinf0x3f3f3f3fvoidsolve(){intn,k;cin>>n>>k;map<int,int>mp;for(inti=0,x;i<n;i++){cin......
  • Codeforces Round 928 (Div. 4) (小白的复盘)
    A.VladandtheBestofFive思路:给你一个长度字符串只包含A和B输出最多的字符解法:按题意来Code:#include<bits/stdc++.h>usingnamespacestd;intmain(){intt;cin>>t;while(t--){strings;cin>>s;intcnt=0;fo......
  • Codeforces Round 928 (Div. 4)(A、B、C、D、E、G)
    目录ABCDEGA统计A、B输出#include<bits/stdc++.h>#defineintlonglong#definerep(i,a,b)for(inti=(a);i<=(b);++i)#definefep(i,a,b)for(inti=(a);i>=(b);--i)#definepiipair<int,int>#definelllonglong#definedbdouble#de......
  • Codeforces Round 928 (Div. 4)
    总结一下最近:感觉过于追求进度了,没有好好的把每题都吃透消化,然后有点依赖题解了,没有好好的思考...B.VladandShapesB题输入二维数组的时候不可以直接两个for循环然后cin,要读入char,再转为数字赋值给二维数组,因为他读入的时候不带有空格而int是要有空格的,这样子比如读000就把它......