LOJ#6002. 「网络流 24 题」最小路径覆盖

Posted Blue233333

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LOJ#6002. 「网络流 24 题」最小路径覆盖相关的知识,希望对你有一定的参考价值。

模板。

技术分享图片
  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 //#include<time.h>
  5 //#include<complex>
  6 //#include<set>
  7 //#include<queue>
  8 #include<algorithm>
  9 #include<stdlib.h>
 10 using namespace std;
 11 
 12 #define LL long long
 13 int qread()
 14 {
 15     char c; int s=0,f=1; while ((c=getchar())<0 || c>9) (c==-) && (f=-1);
 16     do s=s*10+c-0; while ((c=getchar())>=0 && c<=9); return s*f;
 17 }
 18 
 19 //Pay attention to ‘-‘ , LL and double of qread!!!!
 20 
 21 int n,m;
 22 #define maxn 511
 23 #define maxm 15011
 24 struct Edge{int to,next,flow,cap;};
 25 struct Network
 26 {
 27     Edge edge[maxm]; int first[maxn],le,n;
 28     void clear(int N) {le=2; memset(first,0,sizeof(first)); n=N;}
 29     void in(int x,int y,int cap) {Edge &e=edge[le]; e.to=y; e.cap=cap; e.flow=0; e.next=first[x]; first[x]=le++;}
 30     void insert(int x,int y,int cap) {in(x,y,cap); in(y,x,0);}
 31     int dis[maxn]; int que[maxn],cur[maxn],head,tail,s,t;
 32     bool bfs()
 33     {
 34         memset(dis,0,sizeof(dis)); dis[s]=1;
 35         head=tail=0; que[tail++]=s;
 36         while (head!=tail)
 37         {
 38             int x=que[head++];
 39             for (int i=first[x];i;i=edge[i].next)
 40             {
 41                 Edge &e=edge[i];
 42                 if (!dis[e.to] && e.cap>e.flow)
 43                 {
 44                     dis[e.to]=dis[x]+1;
 45                     que[tail++]=e.to;
 46                 }
 47             }
 48         }
 49         return dis[t];
 50     }
 51     int dfs(int x,int a)
 52     {
 53         if (x==t || !a) return a;
 54         int flow=0,f;
 55         for (int &i=cur[x];i;i=edge[i].next)
 56         {
 57             Edge &e=edge[i];
 58             if (dis[e.to]==dis[x]+1 && (f=dfs(e.to,min(e.cap-e.flow,a)))>0)
 59             {
 60                 flow+=f; e.flow+=f;
 61                 edge[i^1].flow-=f; a-=f;
 62                 if (!a) break;
 63             }
 64         }
 65         return flow;
 66     }
 67     int Dinic(int S,int T)
 68     {
 69         s=S; t=T;
 70         int ans=0;
 71         while (bfs())
 72         {
 73             for (int i=1;i<=n;i++) cur[i]=first[i];
 74             ans+=dfs(s,0x3f3f3f3f);
 75         }
 76         return ans;
 77     }
 78 }g;
 79 
 80 bool vis[maxn];
 81 int main()
 82 {
 83     n=qread(); m=qread();
 84     int s=2*n+1,t=s+1; g.clear(t);
 85     for (int i=1,x,y;i<=m;i++)
 86     {
 87         x=qread(); y=qread();
 88         g.insert(x,y+n,1);
 89     }
 90     for (int i=1;i<=n;i++) g.insert(s,i,1),g.insert(i+n,t,1);
 91     int ans=n-g.Dinic(s,t);
 92     for (int i=1;i<=n;i++) if (!vis[i])
 93     {
 94         printf("%d",i);
 95         bool flag=1; int x=i;
 96         while (flag)
 97         {
 98             vis[x]=1;
 99             flag=0;
100             for (int j=g.first[x];j;j=g.edge[j].next)
101             {
102                 Edge &e=g.edge[j]; if (e.to==s) continue;
103                 if (e.cap==e.flow) {flag=1; printf(" %d",x=e.to-n); break;}
104             }
105         }
106         puts("");
107     }
108     printf("%d\n",ans);
109     return 0;
110 }
View Code

 

以上是关于LOJ#6002. 「网络流 24 题」最小路径覆盖的主要内容,如果未能解决你的问题,请参考以下文章

LiberOJ #6002. 「网络流 24 题」最小路径覆盖

LibreOJ #6002. 「网络流 24 题」最小路径覆盖

[loj #6003]「网络流 24 题」魔术球 二分图最小路径覆盖,网络流

网络流24题

LOJ #6010. 「网络流 24 题」数字梯形

[网络流24题] 最小路径覆盖问题