HUST 1342 有上下界最小流
来源:互联网 发布:美空军云计算 编辑:程序博客网 时间:2024/05/16 17:24
Cheat Secretly
Description
HH Big Cow(HBC) has taken part in an interesting treasure finding match. In the match there are N transmitting nodes(labeled from 1 to N), and between these nodes there are M directional roads. In the middle of some roads there may be a “gift-spot”, where a beautiful girl gives a gift to the contestant who passes that road. The one who gets most gifts wins! Winning the match is so easy for HBC, so he is thinking of a more challenging thing —— collecting gifts from ALL the girls. HBC has an amazing ability to achieve this goal: When he comes to a dead end, he can transfer himself to another node arbitrarily. With that ability, of course he can achieve the goal of meeting all the girls, however, cheating is not good! So he decides to use the ability as few as possible. Now he wants to know the fewest times he should use that ability to achieve his goal. NOTE: 1. The graph in the match is a directed acyclic graph (DAG). 2. There is at most one road between any two nodes.
Input
The input contains multiple case. Line 1 an integer T : number of test cases. Line 2 two integer N, M: N for number of nodes. (2 <= N <= 500) M for number of roads. (1 <= M <= 10000) Lines 3..M+2 each line three integers a, b, c: representing a directed roads from a to b. (1 <= a, b <= N) c = 1, then there is a gift spot on this road. c = 0, then there is no gift spot on this road.
Output
For each case output one line representing the fewest number of ability HBC should use.
Sample Input
2
4 2
1 2 1
3 4 1
6 7
1 2 1
2 3 1
3 4 1
1 4 0
5 2 1
3 6 1
5 6 0
Sample Output
Case #1: 2
Case #2: 2
题意:给一个DAG,然后有些边必须走,这样的条件下求最少选择多少路径使得所有的比走边都走完。
解法:
- 根据各个点的入度和出度,首先选起点都是在入度为0的点,路径的终点都是出度为0的点,添加源汇,分别连上。
- 然后,必走的边的下限为1,上限无穷,新建超级源汇,先跑一边sap,在连接源汇,再跑一遍的结果就是最小流。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cassert>using namespace std ;const int INF = 0x3f3f3f3f ;const int N = 511 ;const int M = 5e4 + 11 ;struct Edge { int next , to ; int flow , cap ; Edge(){} Edge(int a , int b , int c) { next = a , to = b , flow = cap = c ; }};int head[N] ; Edge err[M] ; int nedge ;int gap[N] , dis[N] ; int gnode ;int super_source , super_sink , source , sink , start , dest ;int n , m ;void add_edge(int a , int b , int c) { if(head[a] == -1) ++gnode ; if(head[b] == -1) ++gnode ; err[++nedge] = Edge(head[a] , b , c) ; head[a] = nedge ; err[++nedge] = Edge(head[b] , a , 0) ; head[b] = nedge ;}int tot[N] ;bool in[N] , out[N] ;void init() { memset(head , -1 , sizeof(head)) ; nedge = -1 ; gnode = 0 ; memset(in , 0 , sizeof(in)) ; memset(out , 0 , sizeof(out)) ; memset(tot , 0 , sizeof(tot)) ; int a , b , c ; while(m--) { scanf("%d%d%d" ,&a ,&b ,&c) ; if(c == 0) { add_edge(a , b , INF) ; in[b] = true ; out[a] = true ; }else { tot[a] -= 1 , tot[b] += 1 ; add_edge(a , b , INF) ; } } source = 0 , sink = n+1 ; super_source = n+2 , super_sink = n+3 ; for(int i = 1 ; i <= n ; ++i) { if(out[i] == false) add_edge(i , sink , INF) ; if(in[i] == false) add_edge(source , i , INF) ; if(tot[i] > 0) { add_edge(super_source , i , tot[i]) ; }else if(tot[i] < 0) { add_edge(i , super_sink , -tot[i]) ; } }}int dfs(int u , int limit) { if(u == dest) return limit ; int f1 = 0 , f ; int minh = gnode-1 ; for(int i = head[u] ; i != -1 ;i = err[i].next) { int v = err[i].to ; if(err[i].flow > 0) { if(dis[v]+1 == dis[u]) { f = dfs(v , min(limit , err[i].flow)) ; err[i].flow -= f ; err[i^1].flow += f ; limit -= f ; f1 += f ; if(dis[start] >= gnode) return f1 ; if(limit == 0) break ; } minh = min(minh , dis[v]) ; } } if(f1 == 0) { --gap[dis[u]] ; if(gap[dis[u]] == 0) dis[start] = gnode ; dis[u] = minh + 1 ; ++gap[dis[u]] ; } return f1 ;}int sap(int a , int b) { start = a , dest = b ; memset(gap , 0 , sizeof(gap)) ; memset(dis , 0 , sizeof(dis)) ; gap[start] = gnode ; int all = 0 ; while(dis[start] < gnode) all += dfs(start , INF) ; return all ;}int main() { int t , tt = 0 ; scanf("%d" ,&t) ; while(t--) { printf("Case #%d: " , ++tt) ; scanf("%d%d" ,&n ,&m) ; init() ; sap(super_source , super_sink) ; add_edge(sink , source , INF) ; printf("%d\n" , sap(super_source , super_sink)) ; }}
- HUST 1342 有上下界最小流
- hust 1342 (有上下界的最小流)
- HUST 1342Cheat Secretly 有源汇上下界网络流 最小流
- 上下界 最小流
- sug176 Flow construction (有上下界最小流)
- hdu 3157(有上下界的最小流)
- hust1342(流量有上下界的最小流)
- bzoj 2502(有上下界的最小流)
- bzoj 3876(有上下界的最小费用流)
- 【BZOJ2502】清理雪道【有上下界的最小流】
- [BZOJ2502]清理雪道 有上下界的最小流
- [有上下界最小流] BZOJ2502: 清理雪道
- hust 1342 - Cheat Secretly(有源汇有上下界的最小流)
- BZOJ2502【上下界最小流】
- 有上下界的流
- sgu 176 Flow construction (有汇源有上下界的最小流)
- UVA1440 有下界的最小流
- SGU 176 上下界最小流
- 搜索引擎-架构概述(1)
- linux命令之cp
- 数据存储与访问之SharedPreferences(偏好参数保存)
- wampserver服务无法启动(端口冲突问题)
- HDU2037(贪心)
- HUST 1342 有上下界最小流
- 【翻译自mos文章】在win2003 sp1下,遇到无法解释的数据库性能下降
- 第八周项目三(2):分数类中的运算符重载:升级版
- Git的基础用法(一)
- Sql server 没有足够的系统内存来运行此查询
- HDU1002(大数)
- 创建数据库与完成数据增删改查 SQLite数据库
- Myeclipse中怎么设置Servlet模板??
- delphi中combobox键值对