网络流24题之最小路径覆盖

来源:互联网 发布:java冒泡排序经典代码 编辑:程序博客网 时间:2024/05/18 02:00


裸题,无spj,代码里未写第二问。

不过第二问实际上就是最小路径覆盖转化成二分图模型后,找入度为0的点,输出路径即可

最小路径覆盖详讲见:http://blog.csdn.net/qq_34564984/article/details/52778763

代码:


#include<iostream>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cmath>#include<cstring>#include<string>#include<climits>#include<queue>#include<stack>#include<map>#include<set>#define N 402#define M N*N#define inf 1<<30using namespace std;int n,m,s,t;int head[N],pos=-1,cur[N];struct edge{int to,next,c;}e[M];void add(int a,int b,int c){pos++;e[pos].to=b,e[pos].next=head[a],e[pos].c=c,head[a]=pos;}queue<int>Q;bool vis[N];int dis[N];bool bfs(){for(int i=s;i<=t;i++)dis[i]=-1,vis[i]=0;dis[s]=0,vis[s]=1;Q.push(s);while(!Q.empty()){int u=Q.front();Q.pop();for(int i=head[u];i!=-1;i=e[i].next){int v=e[i].to;if(vis[v]||e[i].c<=0)continue;dis[v]=dis[u]+1;vis[v]=1;Q.push(v);}}return vis[t];}int dfs(int u,int a){if(u==t||!a)return a;int f,flow=0;for(int &i=cur[u];i!=-1;i=e[i].next){int v=e[i].to;if(dis[v]==dis[u]+1&&(f=dfs(v,min(a,e[i].c)))>0){flow+=f,a-=f;e[i].c-=f,e[i^1].c+=f;if(!a)break;}}return flow;}int dinic(){int ret=0;while(bfs()){for(int i=s;i<=t;i++)cur[i]=head[i];ret+=dfs(s,inf);}return ret;}void init(){memset(head,-1,sizeof(head));}int main(){freopen("path.in","r",stdin);freopen("path.out","w",stdout);scanf("%d%d",&n,&m);s=0,t=n*2+1;init();for(int i=1;i<=m;i++){int x,y;scanf("%d%d",&x,&y);add(x,y+n,1);add(y+n,x,0);}for(int i=1;i<=n;i++){add(s,i,1);add(i,s,0);add(i+n,t,1);add(t,i+n,0);}printf("%d\n",n-dinic());}



0 0
原创粉丝点击