[网络流24题]最小路径覆盖问题
2016-05-01 16:17
417 查看
话说五一没怎么写过题,
这样的五一怎么能说是完满的呢。。
于是切了一道网络流
乍一看感觉扯不到网络流上来。。其实这是个二分图
把每个点拆开,变成俩个点
之后如果x和y有边就在x1和y2连一条边流量为1
最小路径覆盖就是总点数减最大流量。
代码:
#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define g getchar()
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
inline ll read(){
ll x=0,f=1;char ch=g;
for(;ch<'0'||ch>'9';ch=g)if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=g)x=x*10+ch-'0';
return x*f;
}
inline void out(ll x){
int a[25],wei=0;
if(x<0)putchar('-'),x=-x;
for(;x;x/=10)a[++wei]=x%10;
if(wei==0){puts("0");return;}
for(int j=wei;j>=1;--j)putchar('0'+a[j]);
putchar('\n');
}
struct re{int v,fl,next;}ed[200001];
int dep[10001],dui[10001],head[10001],to[10001],pd[10001];
int n,m,e=1,ans;
inline void ins(int x,int y){
ed[++e]=(re){y,1,head[x]};head[x]=e;
ed[++e]=(re){x,0,head[y]};head[y]=e;
}
bool bfs(){
int tou=1,wei=1;
memset(dep,-1,sizeof(dep));
dui[1]=0;dep[0]=0;
for(;tou<=wei;++tou){
int u=dui[tou];
for(int i=head[u];i;i=ed[i].next)
if(ed[i].fl&&dep[ed[i].v]==-1){
dep[ed[i].v]=dep[u]+1;
dui[++wei]=ed[i].v;
}
}
return dep[n*2+1]!=-1;
}
int dfs(int x,int fl){
if(x==n*2+1)return fl;
int used=0;
for(int i=head[x];i;i=ed[i].next)
if(dep[ed[i].v]==dep[x]+1){
int w=dfs(ed[i].v,min(fl-used,ed[i].fl));
if(w){to[x]=ed[i].v;if(ed[i].v-n>0)pd[ed[i].v-n]=1;}
used+=w;
ed[i].fl-=w;
ed[i^1].fl+=w;
if(used==fl)return fl;
}
if(used==0)dep[x]=-1;
return used;
}
int dinic(){
int ans=0;
for(;bfs();)ans+=dfs(0,inf);
return n-ans;
}
int main(){
// freopen("","r",stdin);
// freopen("","w",stdout);
n=read();m=read();
for(int i=1;i<=m;++i){int x=read(),y=read();ins(x,y+n);}
for(int i=1;i<=n;++i)ins(0,i),ins(i+n,n*2+1);
ans=dinic();
for(int i=1;i<=n;++i){
if(pd[i])continue;
printf("%d",i);
int k=i;
for(;to[k];){
printf(" %d",to[k]-n);
k=to[k]-n;
}
printf("\n");
}
out(ans);
return 0;
}
这样的五一怎么能说是完满的呢。。
于是切了一道网络流
乍一看感觉扯不到网络流上来。。其实这是个二分图
把每个点拆开,变成俩个点
之后如果x和y有边就在x1和y2连一条边流量为1
最小路径覆盖就是总点数减最大流量。
代码:
#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define g getchar()
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
inline ll read(){
ll x=0,f=1;char ch=g;
for(;ch<'0'||ch>'9';ch=g)if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=g)x=x*10+ch-'0';
return x*f;
}
inline void out(ll x){
int a[25],wei=0;
if(x<0)putchar('-'),x=-x;
for(;x;x/=10)a[++wei]=x%10;
if(wei==0){puts("0");return;}
for(int j=wei;j>=1;--j)putchar('0'+a[j]);
putchar('\n');
}
struct re{int v,fl,next;}ed[200001];
int dep[10001],dui[10001],head[10001],to[10001],pd[10001];
int n,m,e=1,ans;
inline void ins(int x,int y){
ed[++e]=(re){y,1,head[x]};head[x]=e;
ed[++e]=(re){x,0,head[y]};head[y]=e;
}
bool bfs(){
int tou=1,wei=1;
memset(dep,-1,sizeof(dep));
dui[1]=0;dep[0]=0;
for(;tou<=wei;++tou){
int u=dui[tou];
for(int i=head[u];i;i=ed[i].next)
if(ed[i].fl&&dep[ed[i].v]==-1){
dep[ed[i].v]=dep[u]+1;
dui[++wei]=ed[i].v;
}
}
return dep[n*2+1]!=-1;
}
int dfs(int x,int fl){
if(x==n*2+1)return fl;
int used=0;
for(int i=head[x];i;i=ed[i].next)
if(dep[ed[i].v]==dep[x]+1){
int w=dfs(ed[i].v,min(fl-used,ed[i].fl));
if(w){to[x]=ed[i].v;if(ed[i].v-n>0)pd[ed[i].v-n]=1;}
used+=w;
ed[i].fl-=w;
ed[i^1].fl+=w;
if(used==fl)return fl;
}
if(used==0)dep[x]=-1;
return used;
}
int dinic(){
int ans=0;
for(;bfs();)ans+=dfs(0,inf);
return n-ans;
}
int main(){
// freopen("","r",stdin);
// freopen("","w",stdout);
n=read();m=read();
for(int i=1;i<=m;++i){int x=read(),y=read();ins(x,y+n);}
for(int i=1;i<=n;++i)ins(0,i),ins(i+n,n*2+1);
ans=dinic();
for(int i=1;i<=n;++i){
if(pd[i])continue;
printf("%d",i);
int k=i;
for(;to[k];){
printf(" %d",to[k]-n);
k=to[k]-n;
}
printf("\n");
}
out(ans);
return 0;
}
相关文章推荐
- 什么是HTTP Headers
- 查看服务器的网络连接状态
- 从自我学习到深层网络
- 深度学习-浅谈CNNs
- HTTP服务介绍
- Google网络请求框架Volley源码浅析(三)
- Android开发本地及网络Mp3音乐播放器(十二)创建NetMusicListAdapter、SearchResult显示网络音乐列表
- Android开发本地及网络Mp3音乐播放器(十二)创建NetMusicListAdapter、SearchResult显示网络音乐列表
- 简单高效可靠的自定义通信协议(传输协议)
- HttpClient用于https交互
- Linux(例如CentOS 7)打开TCP 22端口,基于SSH协议
- HttpServletRequest
- MFC 的 HTTP 请求处理
- HTTP客户端识别与cookie机制
- 目前网络上大部分的网站都是由ASP或PHP开发,并且java平台的软件购买成本不适合中小企业客户,一般适用于银行、国家安全等行业领域
- 目前网络上大部分的网站都是由ASP或PHP开发,并且java平台的软件购买成本不适合中小企业客户,一般适用于银行、国家安全等行业领域
- 做一个自己想要的网络请求框架
- python scrapy 网络采集使用代理的方法
- 网络编程学习——数据链路访问
- 网络编程学习——客户/服务器程序设计范式(一)