1. 程式人生 > >LibreOJ #6002. 「網絡流 24 題」最小路徑覆蓋

LibreOJ #6002. 「網絡流 24 題」最小路徑覆蓋

nic spec -- push ret 技術分享 span line blog

                        內存限制: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 題」最小路徑覆蓋