二分图构图思想!!!
#include <cstdio> #include <iostream> #include <cstdlib> #include <algorithm> #include <queue> #include <cstring> using namespace std; #define ll long long #define re register #define pb push_back; const int N=1e4; const int inf=1e9; inline void read(int &a) { a=0; int d=1; char ch; while(ch=getchar(),ch>'9'||ch<'0') if(ch=='-') d=-1; a=ch^48; while(ch=getchar(),ch>='0'&&ch<='9') a=(a<<3)+(a<<1)+(ch^48); a*=d; } queue <int> q; struct note { int next,dis,v,u; }edge[4*N]; int head[2*N],f[2*N],num,deep[2*N],n,m; inline void init() { for(re int i=1;i<=n;i++) f[i]=i; memset(head,0xff,sizeof(head)); num=-1; } inline void add(int u,int v,int dis) { edge[++num].next=head[u]; edge[num].v=v; edge[num].u=u; edge[num].dis=dis; head[u]=num; } inline bool bfs(int s,int t) { while(!q.empty()) q.pop(); memset(deep,0x7f,sizeof(deep)); deep[s]=0; q.push(s); while(!q.empty()) { int now=q.front(); q.pop(); for(re int i=head[now];i!=-1;i=edge[i].next) { if(deep[edge[i].v]>inf&&edge[i].dis) { deep[edge[i].v]=deep[now]+1; q.push(edge[i].v); } } } if(deep[t]<inf) return true; return false; } inline int dfs(int now,int t,int limit) { if(now==t||!limit) return limit; int flow=0,x; for(re int i=head[now];i!=-1;i=edge[i].next) { if(deep[now]+1==deep[edge[i].v]&&(x=dfs(edge[i].v,t,min(edge[i].dis,limit)))) { flow+=x; edge[i].dis-=x; edge[i^1].dis+=x; limit-=x; if(!limit) break; } } return flow; } inline int dinic(int s,int t) { int ans=0; while(bfs(s,t)) ans+=dfs(s,t,inf); return ans; } inline void write(int x) { printf("%d ",x); for(re int i=head[x];i!=-1;i=edge[i].next) if(!edge[i].dis&&edge[i].v>n) write(edge[i].v-n); } inline int getv(int v){return f[v]=v==f[v]?v:getv(f[v]);} int main() { //freopen("in.txt","r",stdin); read(n); read(m); init(); int s=0,t=(n<<1)+1; for(re int i=0;i<m;i++) { int x,y; read(x); read(y); add(x,n+y,1); add(n+y,x,0); } for(re int i=1;i<=n;i++) add(s,i,1),add(i,s,0); for(re int i=n+1;i<=(n<<1);i++) add(i,t,1),add(t,i,0); int ans=n-dinic(s,t); for(re int i=0;i<=num;i++) if(edge[i].u>=1&&edge[i].u<=n&&edge[i].v>n&&edge[i].v<t&&!edge[i].dis) f[getv(edge[i].v-n)]=getv(edge[i].u); for(re int i=1;i<=n;i++) if(f[i]==i) write(i),putchar('\n'); printf("%d",ans); return 0; }
来源:https://www.cnblogs.com/acm1ruoji/p/11107122.html