LibreOJ #6002. 「网络流 24 题」最小路径覆盖
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LibreOJ #6002. 「网络流 24 题」最小路径覆盖相关的知识,希望对你有一定的参考价值。
内存限制:256 MiB 时间限制:1000 ms 标准输入输出
题目类型:传统 评测方式:Special Judge
上传者: 匿名
网络流 最大流
#include <cstring> #include <cstdio> #include <queue> #define N 6005 #define inf 0x3f3f3f3f using namespace std; bool flag[N]; int n,m,dep[N],nextt[N<<1],to[N<<1],flow[N<<1],head[N],cnt=1,Next[N]; inline void ins(int u,int v,int l) { nextt[++cnt]=head[u]; to[cnt]=v; flow[cnt]=l; head[u]=cnt; } bool bfs(int s,int t) { for(int i=s;i<=t;++i) dep[i]=-1; dep[s]=0; queue<int>q; q.push(s); for(int now;!q.empty();) { now=q.front(); q.pop(); for(int i=head[now];i;i=nextt[i]) { int v=to[i]; if(dep[v]==-1&&flow[i]) { dep[v]=dep[now]+1; if(v==t) return true; q.push(v); } } } return false; } inline int min(int a,int b) {return a>b?b:a;} int dfs(int now,int t,int Limit) { if(now==t||!Limit) return Limit; int f,ret=0; for(int i=head[now];i;i=nextt[i]) { int v=to[i]; if(dep[v]==dep[now]+1&&flow[i]&&(f=dfs(v,t,min(flow[i],Limit)))) { if(v>n) flag[v-n]=1; flow[i]-=f; flow[i^1]+=f; Limit-=f; ret+=f; Next[now]=v; if(!Limit) break; } } if(Limit!=ret) dep[now]=-1; return ret; } int dinic(int s,int t) { int ret=0; for(;bfs(s,t);ret+=dfs(s,t,inf)); return ret; } int Main() { scanf("%d%d",&n,&m); int s=0,t=n*2+1; for(int x,y;m--;) { scanf("%d%d",&x,&y); ins(x,y+n,inf); ins(y+n,x,0); } for(int i=1;i<=n;++i) { ins(s,i,1);ins(i,s,0); ins(i+n,t,1);ins(t,i+n,0); } int ans=n-dinic(s,t); for(int i=1;i<=n;++i) { if(flag[i]) continue; int now=i; printf("%d ",now); for(;Next[now];now=Next[now]) { if(Next[now]>n) Next[now]-=n; printf("%d ",Next[now]); } printf("\\n"); } printf("%d\\n",ans); return 0; } int sb=Main(); int main(int argc,char *argv[]) {;}
以上是关于LibreOJ #6002. 「网络流 24 题」最小路径覆盖的主要内容,如果未能解决你的问题,请参考以下文章
LibreOJ #6001. 「网络流 24 题」太空飞行计划 最大权闭合图