hust1342(流量有上下界的最小流)
来源:互联网 发布:php url补全函数 编辑:程序博客网 时间:2024/05/16 05:49
题意:
给出一个有向无环图(DAG),我们规定有一些边是必须走的,当走到一个出度是0的点时,我们可以瞬移到任何一个我们想去的点,自选起点,走遍所有的必须走的边,使得瞬移次数最少。
思路:
这类题完全没做过啊,赛后问了过了这道题的同学,才知道这么个东西,具体怎么建图模板里都告诉了,红书上就有。
代码:
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>#include<cstdlib>#include<climits>#include<queue>#include<stack>#include<set>#include<string>#include<vector>using namespace std;const int maxn = 510, maxm = maxn * maxn;const int inf = 1000000000;class MaxFlow//一个挺快的模板,比一般的MaxFlow快,我也不知道为什么。。。{private: int next[maxm*2]; int num[maxm*2]; int a[maxn*2]; int row_sum[maxn]; int col_sum[maxn]; int n , m, K; int d[maxn*2], st[maxn*2], cod[maxn][maxn]; int h[maxn*2], vh[maxn*2]; bool don[maxm*2],in[maxn*2]; int dfs(int, int); bool visit(int, int);public: int T; int r[maxm*2]; MaxFlow() {} int Addedge(int, int, int); int Run(); bool FindCircle(); void Init(int m) { memset(a, 0, sizeof(a)); tt = 1; T = m; } int tt; ~MaxFlow() {}} mf;int MaxFlow::Addedge(int x,int y,int rr){ next[++tt]=a[x]; num[tt]=y; r[tt]=rr; a[x]=tt; next[++tt]=a[y]; num[tt]=x; r[tt]=0; a[y]=tt; return tt;}int MaxFlow::dfs(int x,int y){ if (x==T) return y; int sig=st[x],minh=T+1; do { if (r[st[x]]) { if (h[num[st[x]]]+1==h[x]) { int k=dfs(num[st[x]],min(y,r[st[x]])); if (k) { r[st[x]]-=k; r[st[x]^1]+=k; return k; } } minh=min(minh,h[num[st[x]]]+1); if (h[0]>T) return 0; } st[x]=next[st[x]]; if (st[x]==0) st[x]=a[x]; } while (sig!=st[x]); if (vh[h[x]]--==0) h[0]=T+1; vh[h[x]=minh]++; return 0;}int MaxFlow::Run(){ for (int i=0; i<=T; i++) h[i]=vh[i]=0; for (int i=0; i<=T; i++) st[i]=a[i]; vh[0]=T+1; int ret=0; while (h[0]<=T) ret+=dfs(0,K+1); return ret;}bool MaxFlow::visit(int x,int ed){ if (don[ed]) return in[x]; don[ed]=true; in[x]=true; for (int p=a[x]; p; p=next[p]) { if (r[p] && (ed^p)!=1) if (visit(num[p],p)) return true; } in[x]=false; return false;}bool MaxFlow::FindCircle(){ for (int i=0; i<=T; i++) in[i]=false; for (int i=1; i<=tt; i++) don[i]=false; for (int i=2; i<=tt; i++) { if (r[i] && !don[i]) { in[num[i^1]]=true; if (visit(num[i],i)) return true; in[num[i^1]]=false; } } return false;}int cnt[maxn]; //节点的度int main(){ int t;scanf("%d",&t);int cas=1;while(t--) { int n, m; scanf("%d%d", &n, &m); int ss = 0, tt = n+3;//源点和汇点 int s = n + 2, t = n+1;//附加源点和附加汇点 mf.Init(tt);//注意模板的坑,此模板的源点一定是0,不能自己设定,汇点就是tt for (int i = 1; i <= n; i++) { mf.Addedge(s, i, inf); mf.Addedge(i, t, inf); } memset(cnt, 0, sizeof cnt); int sum = 0; while (m--) { int u, v, w; scanf("%d%d%d", &u, &v, &w); if (w) { sum++; cnt[u]--; cnt[v]++; } mf.Addedge(u, v, inf); } for (int i = 1; i <= n; i++) { if (cnt[i] < 0) mf.Addedge(i, tt, -cnt[i]); else mf.Addedge(ss, i, cnt[i]); } mf.Run(); int fuck = mf.Addedge(t, s, sum); mf.Run(); printf("Case #%d: %d\n", cas++, sum - mf.r[fuck^1]);//为什么异或1,因为这个模板的返回值返回的是反向边的流量,所以^1了才是正向边的流量 } return 0;}
0 0
- hust1342(流量有上下界的最小流)
- 流量有上下界的网络的最大流和最小流算法
- hust 1342 (有上下界的最小流)
- hdu 3157(有上下界的最小流)
- bzoj 2502(有上下界的最小流)
- bzoj 3876(有上下界的最小费用流)
- 【BZOJ2502】清理雪道【有上下界的最小流】
- [BZOJ2502]清理雪道 有上下界的最小流
- HUST 1342 有上下界最小流
- 有上下界的流
- POJ 2396:Budget (有流量上下界的网络流)
- 上下界 最小流
- UVA1440 有下界的最小流
- sgu 176 Flow construction (有汇源有上下界的最小流)
- hdu 3157 流量有上下限的最小流
- sug176 Flow construction (有上下界最小流)
- [有上下界最小流] BZOJ2502: 清理雪道
- 网络流(最大流、最小费用最大流、有上下界的网络流)
- 第一次开通博客,以后这里就是我的独家技术基地
- iOS 利用UIScrollView 对图片进行缩放
- MVC中的筛选器
- 社説 20150831 旧ソ連抑留者 「シベリア以外」の解明も急げ
- 如何使用UIAutomation进行iOS 自动化测试(Part I)
- hust1342(流量有上下界的最小流)
- 用lazarus快速创建xml格式文件
- IOS 字符串删除某一个字符
- javascript面试题 之 js中this关键字的用法
- 天台山的读音
- 用tdm编译64bit qt版本的mysql驱动
- 分出奇偶数
- 百度笔试题
- LeetCode(46)Permutations