网络流做法最要是建边
将m点分割限流 建立一个起点 连接2个点在于n相连 不过一个流量是inf 一个是k 再把n m连起来 跑最大流即可二分图把 n m的边建2遍(注意开的n'是一个新的节点)
跑二分图的时候注意顺序,先跑原本的n的节点 再跑之后新建的n个节点 因为要保证优先不扩流(不用k) 但这样有可能会出现用别的边的流量的情况出现 所以在跑完二分图之后 判断一下原本的n个点可以用的最大流量 在 可用的最大流量+k 与 二分图结果 取min即可
网络流#includeusing namespace std;#define ll long long#define mem(a,b) memset(a,b,sizeof(a))#define inf 0x3f3f3f3fconst int maxn=5e6+10;struct edge{ int u,v,w,next;}e[maxn*2];int n,m,k,maxflow,dep[maxn*2],tot=-1,g[maxn*2];void creatEdge(int u,int v,int w){ e[++tot]=(edge){u,v,w,g[u]}; g[u]=tot;}int bfs(int s,int t){ queue q; mem(dep,-1); dep[s]=0; q.push(s); while(!q.empty()) { int now=q.front(); q.pop(); for(int i=g[now];i!=-1;i=e[i].next) { int v=e[i].v; if(dep[v]==-1&&e[i].w) { dep[v]=dep[now]+1; q.push(v); } } } return dep[t]==-1?0:1;}int dfs(int s,int t,int lim){ if(!lim||s==t) return lim; int flow=0,f; for(int i=g[s];i!=-1;i=e[i].next) { int v=e[i].v,w=e[i].w; if(dep[v]==dep[s]+1&&(f=dfs(v,t,min(lim,w)))) { flow+=f; lim-=f; e[i].w-=f; e[i^1].w+=f; if(!lim) break; } } return flow;}void Dinic(int s,int t){ int tot=0; while(bfs(s,t)) maxflow+=dfs(s,t,inf);}int main(){ int s,t; mem(g,-1); cin>>n>>m>>k; int tp=n+m; for(int i=1;i<=n;i++) { int tt; cin>>tt; for(int j=1;j<=tt;j++) { int v; cin>>v; creatEdge(2*m+i,v,1); creatEdge(v,2*m+i,0); } } int pos=4*500+1; for(int i=1;i<=m;i++) { creatEdge(i,i+m,1); creatEdge(i+m,i,0); creatEdge(i+m,pos+1,1); creatEdge(pos+1,i+m,0); } for(int i=1;i<=n;i++) { creatEdge(pos+2,2*m+i,1); creatEdge(2*m+i,pos+2,0); creatEdge(pos+3,2*m+i,1); creatEdge(2*m+i,pos+3,0); } creatEdge(pos+4,pos+3,500); creatEdge(pos+3,pos+4,0); creatEdge(pos+4,pos+2,k); creatEdge(pos+2,pos+4,0); s=pos+4,t=pos+1; Dinic(s,t);// cout< <<" "<<
二分图#includeusing namespace std;const int maxn=6e5+10;struct node{ int u,v,next;}e[maxn];int n,m,k,temp;int g[maxn],vis[maxn],xM[maxn],yM[maxn],tot=0;int chk[maxn];void make(int u,int v){ e[++tot]={u,v,g[u]}; g[u]=tot;}int searchpath(int u){ for(int i=g[u];i;i=e[i].next) { int v=e[i].v; if(!chk[v]) { chk[v]=1; if(yM[v]==-1||searchpath(yM[v])) { yM[v]=u; xM[u]=v; return 1; } } } return 0;}int Maxmatch(){ int u,ret=0; memset(xM,-1,sizeof(xM)); memset(yM,-1,sizeof(yM)); for(u=m+1;u<=temp;u++) { if(xM[u]==-1) { memset(chk,0,sizeof(chk)); if(searchpath(u)) ret++; } } return ret;}int main(){ cin>>n>>m>>k; temp=m; for(int i=1;i<=n;i++) { int t; cin>>t; temp++; for(int j=1;j<=t;j++) { int now; cin>>now; make(temp,now); make(temp+n,now); } } temp+=n; int ans=Maxmatch(); int tt=0; for(int u=m+1;u<=m+n;u++) if(xM[u]!=-1) tt++; cout< <