boxmoe_header_banner_img

欢迎来到DRheEheAM的blog

加载中

文章导读

Week4 Day5 | Aug. 15th


avatar
DRheEheAM_Gary 2025年8月15日 13

S+二分图与网络流初步

A. 生成二分图

最开始理解错了题意写了一个$O(n^2)$的算法直接炸开了😅

感谢ooliver救我一命(
正解的话是bfs染色并统计两边大小,计算答案:
$$
ans=\sum [v_1 v_2+\frac{(v_1+v_2)\times(n-v_1-v_2)}{2}] – m
$$
最好记得开个 long long (awa
还有记得判断无解的时候要看两个是不是都为0不然炸了(

#include<bits/stdc++.h>
using namespace std;
#define intc const int
#define int long long
#define Cios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
intc N=2e5+10;
int n,m,ans=0,cl[N];
vector<int> g[N];
pair<int,int> bfs(int x) {
    int v1=0,v2=0;
    queue<int> q;
    q.push(x);
    cl[x]=1;
    v1++;
    while (q.size()) {
        int u=q.front();
        q.pop();
        for (int v:g[u]) {
            if (cl[v]) {
                if (cl[v]!=cl[u]) continue;
                return make_pair(0,0);
            }
            if (cl[u]==1) {
                v2++;
                cl[v]=2;
            }
            else {
                v1++;
                cl[v]=1;
            }
            q.push(v);
        }
    }
    return make_pair(v1*v2,v1+v2);
}
signed main() {
    cin>>n>>m;
    for (int i=1;i<=m;i++) {
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    for (int i=1;i<=n;i++) {
        if (!cl[i]) {
            pair<int,int> v=bfs(i);
            if (v.first==0&&v.second==0) {
                cout<<0;
                return 0;
            }
            ans+=v.first*2+v.second*(n-v.second);
            //cerr<<v.first<<" "<<v.second<<endl;;
        }
    }
    cout<<ans/2-m<<endl;
    return 0;
}
C++

B. 图上同色最远(ARC165 C)

先按二分图染色考虑;
不难发现(并非不难),若给定的图是二分图,按二分图染色得到的答案为图上所有三个点的路径长度最小值
考虑非二分图,显然奇环上必有相邻同色点。故答案又有了一个新的上界:所有奇环边权最大值的最小值。
考虑如何得到所有奇环边权最大值的最小值,将边按边权从小到大排序,在并查集判二分图时,若发现连上这条边会出现奇环,就将上界与当前边权取 min,并取消连边即可。

#include<bits/stdc++.h>
using namespace std;
#define intc const int
#define int long long
#define Cios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
intc N=2e5+5;
int n,m,ans=INT_MAX,fi[N],se[N],fa[N<<1];
struct edge {
    int u,v,w;
}e[N];
int get(int x) {
    return x==fa[x]?x:fa[x]=get(fa[x]);
}
signed main() {
    Cios;
    memset(fi,0x3f,sizeof fi);
    memset(se,0x3f,sizeof se);
    cin>>n>>m;
    for(int i=1;i<=m;i++) {
        int u,v,w;
        cin>>u>>v>>w;
        e[i]={u,v,w};
        if (w<fi[u]) {
            se[u]=fi[u];
            fi[u]=w;
        }
        else if (w<se[u]) se[u]=w;
        if (w<fi[v]) {
            se[v]=fi[v];
            fi[v]=w;
        }
        else if (w<se[v]) se[v]=w;
    }
    for (int i=1;i<=n<<1;i++) fa[i]=i;
    for (int i=1;i<=n;i++) ans=min(ans,se[i]+fi[i]);
    sort(e+1,e+m+1,[](edge a,edge b) {return a.w<b.w;});
    for (int i=1;i<=m;i++) {
        if (get(e[i].u)==get(e[i].v)) ans=min(ans,e[i].w);
        else fa[get(e[i].u)]=get(e[i].v+n),fa[get(e[i].v)]=get(e[i].u+n);
    }
    cout<<ans;
    return 0;
}
C++


评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字
插入代码
DRheEheAM Blog

返回

您的消息已发送

需要反馈文章问题?点击这里...

警告
警告
警告
警告

隐私政策...

请给出具有实用,建设性的建议!
注意:若频繁发送邮件,或发送过多无意义邮件,可能会遭到临时封禁,严重者永久封禁!

警告。