cf976f Minimal k-covering

Enumeration \(k\) , for each point \(i\) we delete at most \(deg_i-k\) edges, connecting the source point to the first part and the second part to the sink, the capacity is \ (deg_i-k\) , the original edge is connected, and the capacity is \(1\) , so that every time an edge of the original edge in the network flow graph flows through, it means that this edge can be deleted. That is, the edge that does not flow is the answer when \(k\)

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
int nu, nv, n, m, ss, tt, hea[4005], deg[4005], cnt, maxFlow, lev[4005], cur[4005];
const int oo=0x3f3f3f3f;
queue<int> d;
vector<int> vec[4005];
struct Edge{
    int too, nxt, val;
}edge[50005], orz[2005];
void add_edge(int fro, int too, int val){
    edge[cnt].nxt = hea[fro];
    edge[cnt].too = too;
    edge[cnt].val = val;
    hea[fro] = cnt++;
}
void addEdge(int fro, int too, int val){
    add_edge(fro, too, val);
    add_edge(too, fro, 0);
}
bool bfs(){
    memset(lev, 0, sizeof(lev));
    lev[ss] = 1;
    d.push(ss);
    while(!d.empty()){
        int x=d.front();
        d.pop();
        for(int i=hea[x]; i!=-1; i=edge[i].nxt){
            int t=edge[i].too;
            if(!lev[t] && edge[i].val>0){
                lev[t] = lev[x] + 1;
                d.push(t);
            }
        }
    }
    return lev[tt]!=0;
}
int dfs(int x, int lim){
    if(x==tt)   return lim;
    int addFlow=0;
    for(int &i=cur[x]; i!=-1; i=edge[i].nxt){
        int t=edge[i].too;
        if(lev[t]==lev[x]+1 && edge[i].val){
            int tmp=dfs(t, min(lim-addFlow, edge[i].val));
            edge[i].val -= tmp;
            edge[i^1].val += tmp;
            addFlow += tmp;
            if(addFlow==lim)    break;
        }
    }
    return addFlow;
}
void dinic(){
    while(bfs()){
        for(int i=ss; i<=tt; i++)   cur[i] = hea[i];
        maxFlow += dfs(ss, oo);
    }
}
int main(){
    memset(hea, -1, sizeof(hea));
    cin>>nu>>nv>>m;
    n = nu + nv;
    ss = 0; tt = n + 1;
    int minDeg=0x3f3f3f3f;
    for(int i=1; i<=m; i++){
        scanf("%d %d", &orz[i].too, &orz[i].nxt);
        orz[i].nxt += nu;
        deg[orz[i].too]++;
        deg[orz[i].nxt]++;
    }
    for(int i=1; i<=n; i++)
        minDeg = min(minDeg, deg[i]);
    for(int i=1; i<=nu; i++)
        addEdge(ss, i, deg[i]-minDeg-1);
    for(int i=1; i<=nv; i++)
        addEdge(nu+i, tt, deg[nu+i]-minDeg-1);
    int tmp=cnt;
    for(int i=1; i<=m; i++)
        addEdge(orz[i].too, orz[i].nxt, 1);
    for(int i=minDeg; i>=0; i--){
        for(int j=0; j<tmp; j+=2)
            edge[j].val++;
        dinic();
        for(int j=tmp; j<cnt; j+=2)
            if(edge[j].val)
                vec[i].push_back((j-tmp)/2+1);
    }
    for(int i=0; i<=minDeg; i++){
        printf("%d ", vec[i].size());
        for(int j=0; j<vec[i].size(); j++)
            printf("%d ", vec[i][j]);
        printf("\n");
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325261587&siteId=291194637