您的位置:首页 > 理论基础 > 计算机网络

【网络流】最小路径覆盖问题

2017-03-06 15:31 197 查看
最近在学网络流,老师叫我做这题,然后就A了。。

原题地址:https://www.luogu.org/problem/show?pid=2764

解题思路:网络流跑最大匹配,路径数就是节点数-匹配数。

附代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#define For(i,a,b) for (int i=a; i<=b; i++)
#define Ford(i,a,b) for (int i=a; i>=b; i--)
#define File(fn) freopen(fn".in","r",stdin); freopen(fn".out","w",stdout);
#define mem(qaq,num) memset(qaq,num,sizeof(qaq));
#define ll long long
#define mod 1000000007
#define INF 2000000000
using namespace std;
struct zxy{
int next,to,v;
}edge[2000001];
int n,cnt=1,head[8001],lev[8001],to[8001],que[8001],m;
bool b[4001];
inline int in(){
int x=0,f=1;
char ch=getchar();
while (ch<'0'||ch>'9') f=ch=='-'?-1:1,ch=getchar();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline void ins(int x,int y,int l){
edge[++cnt].to=y,edge[cnt].next=head[x],edge[cnt].v=l,head[x]=cnt;
edge[++cnt].to=x,edge[cnt].next=head[y],edge[cnt].v=0,head[y]=cnt;
}
inline bool bfs(int s,int e){
mem(lev,-1);
int t=1,h=0;
que[0]=s;
lev[s]=0;
do{
h++;
int k=head[que[h]];
while(k){
if (lev[edge[k].to]==-1&&edge[k].v){
lev[edge[k].to]=lev[que[h]]+1;
que[++t]=edge[k].to;
}
k=edge[k].next;
}
}while(h<t);
return lev[e]!=-1;
}
inline int dfs(int u,int v,int f){
if (u==v) return f;
int used=0,k=head[u];
while(k){
if (edge[k].v&&lev[edge[k].to]==lev[u]+1){
int w=dfs(edge[k].to,v,min(edge[k].v,f-used));
if (w){
to[u]=edge[k].to;
if (edge[k].to>n) b[edge[k].to-n]=1;
}
used+=w;
edge[k].v-=w;
edge[k^1].v+=w;
if (used==f) return used;
}
k=edge[k].next;
}
return used;
}
int dinic(int s,int t){
int flow=0;
while(bfs(s,t))
flow+=dfs(s,t,INF);
return flow;
}
void read(){
n=in(),m=in();
int x,y;
For(i,1,m) {
x=in(),y=in();
ins(x,y+n,INF);
}
For(i,1,n) ins(0,i,1),ins(i+n,(n<<1|1),1);
}
void solve(){
int ans=n;
ans-=dinic(0,2*n+1);
For(i,1,n)
if (b[i]) continue;
else{
printf("%d",i);
int k=i;
while(to[k]){
k=to[k]-n;
printf(" %d",k);
}
printf("\n");
}
printf("%d",ans);
}
int main(){
read();
solve();
}


本文由Melacau编写,Melacau代表M星向您问好,如果您不是在我的博客http://www.cnblogs.com/Melacau上看到本文,请您向我联系,email:13960948839@163.com.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: