Network flow problem [24] the minimum path cover problem

Face questions

https://www.luogu.org/problem/P2764

answer

Forgive me too immature year, to $ dinic $ misspelled.

#include<cstdio>
#include<iostream>
#define ri register int
#define N 20000

using namespace std;
int n,m;

int head[N],cnt=1;
int dep[N],que[N],nex[N],pre[N];
int to[7*N],nxt[7*N],wei[7*N],cur[N];
bool inq[N],vis;

void add(int u,int v,int w) {
  ++cnt;
  nxt[cnt]=head[u];
  to[cnt]=v;
  wei[cnt]=w;
  head[u]=cnt;
}

bool bfs() {
  for (ri i=1;i<=2*n+2;i++) dep[i]=987654321,cur[i]=head[i],inq[i]=0;
  que[1]=2*n+1; dep[2*n+1]=1; inq[2*n+1]=1;
  int tail=1,hd=1;
  while (tail<=hd) {
    int x=que[tail];
    tail++;
    inq[x]=0;
    for (ri i=head[x];i;i=nxt[i]) if (dep[x]+1<dep[to[i]] && wei[i]) {
      dep[to[i]]=dep[x]+1;
      if (!inq[to[i]]) que[++hd]=to[i],inq[to[i]]=1;
    }
  }
  return dep[2*n+2]<=n;
}

int dfs(int x,int mi) {
  if (x==2*n+2) {
    vis=1;
    return mi;
  }
  int used=0;
  int rlow;
  for (ri i=cur[x];i;i=nxt[i])  {
    cur[x]=i;
    if (wei[i] && dep[to[i]]==dep[x]+1) {
        rlow=dfs(to[i],min(mi-used,wei[i]));
        if (rlow) {
          if (1<=x && x<=n && n<to[i] && to[i]<=2*n) {
            nex[x]=to[i]-n;
            pre[to[i]-n]=x;
          }
          used+=rlow;
          wei[i]-=rlow;
          wei[i^1]+=rlow;
          if (used==mi) return used;
        }
    }
  }
  return used;
}

void dicnic(){
  while (bfs()) {
    vis=1;
    while (vis) {
      vis=0;
      dfs(2*n+1,0x3f3f3f3f);
    }
  }
}

void print(int x) {
  printf("%d ",x);
  if (nex[x]) print(nex[x]);
}

int main(){
  int u,v;
  scanf("%d %d",&n,&m);
  for (ri i=1;i<=m;i++) {
    scanf("%d %d",&u,&v);
    add(u,n+v,1); add(n+v,u,0);
  }
  for (ri i=1;i<=n;i++) add(2*n+1,i,1),add(i,2*n+1,0);
  for (ri i=n+1;i<=2*n;i++) add(i,2*n+2,1),add(2*n+2,i,0);
  dicnic();
  int ans=0;
  for (ri i=1;i<=n;i++) if (!pre[i]) print(i),puts(""),ans++;
  cout<<ans<<endl;
}

 

Guess you like

Origin www.cnblogs.com/shxnb666/p/11285906.html