swust1738: 最小路径覆盖问题
来源:互联网 发布:vc网络编程开发与实战 编辑:程序博客网 时间:2024/04/27 19:30
链接:http://www.oj.swust.edu.cn/problem/show/1738
题意:中文题。
分析:网络流24题第三题。最小路径覆盖,我们可以转换成二分图匹配去做,将点i拆成点i和点i+n,每一条边(i,j)变成i与j+n相连,然后匹配。为什么能转呢?我们可以先将这n个点看成是孤立的,也就是n条路径覆盖,然后我们试着加边,每加一条边将一对路径的首尾连起来那么路径数就少了一条,那么最后答案ans=n-最大匹配数。还不清楚的话可以自己画画图理解下,输出路径的话沿着匹配的方向就能输出了。
代码:
#include<map>#include<set>#include<cmath>#include<queue>#include<bitset>#include<math.h>#include<vector>#include<string>#include<sstream>#include<stdio.h>#include<cstring>#include<iostream>#include<algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int N=305;const int MAX=1000000100;const int mod=100000000;const int MOD1=1000000007;const int MOD2=1000000009;const double EPS=0.00000001;typedef long long ll;const ll MOD=998244353;const int INF=1000000010;const double pi=acos(-1.0);typedef double db;typedef unsigned long long ull;int tot,u[N],v[N*N],cap[N*N],flow[N*N],pre[N*N];void add(int a,int b,int c,int f) { v[tot]=b;cap[tot]=c;flow[tot]=f;pre[tot]=u[a];u[a]=tot++;}bool q[N];int n,d[N],dis[N],head[N];bool bfs(int a,int b) { int i,l=1,r=1; memset(q,0,sizeof(q)); d[1]=a;q[a]=1;dis[a]=0; for (;l<=r;l++) for (i=u[d[l]];i!=-1;i=pre[i]) if (!q[v[i]]&&cap[i]>flow[i]) q[v[i]]=1,d[++r]=v[i],dis[v[i]]=dis[d[l]]+1; return q[b];}int dfs(int a,int b,int en) { if (a==en||b==0) return b; int ret=0,f; for (int& i=u[a];i!=-1;i=pre[i]) if (dis[v[i]]==dis[a]+1&&(f=dfs(v[i],min(b,cap[i]-flow[i]),en))>0) { flow[i]+=f;flow[i^1]-=f; b-=f;ret+=f; if (b==0) break ; } return ret;}void out(int a) { printf("%d ", a);q[a]=1; for (int i=u[a];i!=-1;i=pre[i]) if (v[i]!=0&&v[i]!=2*n+1&&flow[i]&&!q[v[i]-n]) out(v[i]-n);}int main(){ int a,b,i,m,ans=0; scanf("%d%d", &n, &m); tot=0;memset(u,-1,sizeof(u)); for (i=1;i<=m;i++) { scanf("%d%d", &a, &b); add(a,b+n,1,0);add(b+n,a,0,0); } for (i=1;i<=n;i++) { add(0,i,1,0);add(i,0,0,0); add(i+n,2*n+1,1,0);add(2*n+1,i+n,0,0); } for (i=0;i<=2*n+1;i++) head[i]=u[i]; while (bfs(0,2*n+1)) { ans+=dfs(0,INF,2*n+1); for (i=0;i<=2*n+1;i++) u[i]=head[i]; } memset(q,0,sizeof(q)); for (i=1;i<=n;i++) if (!q[i]) { out(i);printf("\n"); } printf("%d\n", n-ans); return 0;}
0 0
- swust1738: 最小路径覆盖问题
- 最小路径覆盖问题
- 最小路径覆盖问题
- 最小路径覆盖问题
- 最小路径覆盖问题
- 最小路径覆盖问题
- 若干最小路径覆盖问题
- poj1511 最小路径覆盖问题
- luogu2764 最小路径覆盖问题
- 最小路径覆盖问题 最小路径覆盖+输出解
- 最小路径覆盖问题(最小路径覆盖)
- 最小路径覆盖问题 (网络流解法)
- 网络流3最小路径覆盖问题
- [codevs 1904] 最小路径覆盖问题
- 【网络流】最小路径覆盖问题
- poj 2594(最小路径覆盖问题)
- 最小路径覆盖问题(二分图)
- Codevs 1904 最小路径覆盖问题
- Study notes in the first week in GeekBand
- Android Volley完全解析(四),带你从源码的角度理解Volley
- thinkphp __PUBLIC__的定义 __ROOT__等常量的定义
- 【解题报告】CodeVS3728 联合权值
- 汽车基本知识
- swust1738: 最小路径覆盖问题
- C#接口实例详解
- MFRC522应用详解
- 【刷题之路】数值的整数次方
- 接收和发送短信
- jquery产品树形介绍页特效
- 接收和发送短信
- mybatis之 SqlSessionFactory单例创建
- thinkcmf整合ucenter