BZOJ2400:[Spoj 839]Optimal Marks (Minimum secant)

Posted by mmj on Sat, 11 Jul 2020 17:10:53 +0200

Portal

Topic:
Given an undirected graph, the point values of some points have already been given, and the point values of some points can be freely chosen.Defines an edge with a weight of two points XOR.These points are required to be assigned a value so that the weights of the last edge are the smallest, and the point values at this time are output. If there are multiple schemes that make the weights of the edge the smallest, then the output makes the point values and the smallest schemes.

Questions:
That's a good question.

First, XOR bits are independent and can be calculated separately.

It is found that for each consideration, the equivalent is to assign a value of 0,1 to an undetermined point, so that the two adjacent points are different or minimized.

The original problem is essentially equivalent to dividing points into S,T sets, where the contribution of edges between points of different sets is 1, and then becomes the template of the smallest cut.

Then there's how to handle point values and minimizations.Similarly, for the residual network shrink point, it is found that the strong connection of S set at this time is the minimum point set, so it is good to dfs the origin directly.

#include<bits/stdc++.h>
using namespace std;
inline int rd(){
    char ch=getchar();int i=0,f=1;
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){i=(i<<1)+(i<<3)+ch-'0';ch=getchar();}
    return i*f;
}
const int Maxn=5e2+50,Maxm=6e3+50;
int n,m,lev[Maxn],cur[Maxm],vis[Maxn],vt,a[Maxn],a2[Maxn],pos; 
queue<int>q;
long long ans;
const int src=0,des=501,INF=0x3f3f3f3f;
struct G{
    int g[Maxn],v[Maxm],c[Maxm],nt[Maxm],ec;
    G(){ec=1;}
    inline void add(int x,int y,int o){++ec;nt[ec]=g[x];g[x]=ec;v[ec]=y;c[ec]=o;}
    inline void init(){
        for(int i=1;i<=n;i++)if(a[i]>=0&&(a[i]&(1<<pos)))add(src,i,INF),add(i,src,0);
        for(int i=1;i<=n;i++)if(a[i]>=0&&(!(a[i]&(1<<pos))))add(i,des,INF),add(des,i,0);
    }
    inline bool bfs(){
        while(!q.empty())q.pop();
        for(int i=0;i<=n;i++)lev[i]=0;
        lev[des]=0;lev[src]=1;q.push(src);
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int j=g[u];j;j=nt[j]){
                if(!c[j]||lev[v[j]])continue;
                lev[v[j]]=lev[u]+1;q.push(v[j]);
                if(v[j]==des)return true;
            }
        }
        return false;
    }
    inline int dinic(const int &x,int f){
        if(x==des)return f;
        int rs=0;
        for(int &j=cur[x];j;j=nt[j]){
            if(!c[j]||(lev[v[j]]!=lev[x]+1))continue;
            int o=dinic(v[j],min(f-rs,c[j]));
            rs+=o;c[j]-=o;c[j^1]+=o;
            if(rs==f)return rs;
        }
        return (lev[x]=0,rs);
    }
    inline void dfs(int now){
        vis[now]=vt;a2[now]|=(1<<pos);
        for(int j=g[now];j;j=nt[j]){
            if(!c[j])continue;
            if(vis[v[j]]!=vt)dfs(v[j]);
        }
    }
    inline int maxflow(){
        int rs=0;
        while(bfs()){
            int t;memcpy(cur,g,sizeof(cur));
            while((t=dinic(src,INF)))rs+=t,memcpy(cur,g,sizeof(cur));
        }
        ++vt;dfs(src);return rs;
    }
}g,g2;
int main(){
    n=rd(),m=rd();
    for(int i=1;i<=n;i++)a[i]=rd();
    for(int i=1;i<=m;i++){
        int x=rd(),y=rd();
        g.add(x,y,1);g.add(y,x,1);
    }
    for(pos=30;pos>=0;pos--){
        g2=g;g2.init();ans+=(1ll<<pos)*g2.maxflow();
    }
    cout<<ans<<endl;ans=0;
    for(int i=1;i<=n;i++)ans+=a2[i];
    cout<<ans<<endl;
} 

Topics: network