POJ 2455 Secret Milking Machine (二分 + 最大流)
2016-01-08 07:32
531 查看
题目大意:
给出一张无向图,找出T条从1..N的路径,互不重复,求走过的所有边中的最大值最小是多少。
算法讨论:
首先最大值最小就提醒我们用二分,每次二分一个最大值,然后重新构图,把那些边权符合要求的边加入新图,在新图上跑网络流。
这题有许多注意的地方:
1、因为是无向图,所以我们在加正向边和反向边的时候,流量都是1,而不是正向边是1,反向边是0。
2、题目中说这样的路径可能不止t条,所以我们在最后二分判定的时候不能写 == t,而是要 >= t。
3、这题很容易T ,表示我T了N遍,弱菜啊。
Codes:
POJ 2455 T 版
给出一张无向图,找出T条从1..N的路径,互不重复,求走过的所有边中的最大值最小是多少。
算法讨论:
首先最大值最小就提醒我们用二分,每次二分一个最大值,然后重新构图,把那些边权符合要求的边加入新图,在新图上跑网络流。
这题有许多注意的地方:
1、因为是无向图,所以我们在加正向边和反向边的时候,流量都是1,而不是正向边是1,反向边是0。
2、题目中说这样的路径可能不止t条,所以我们在最后二分判定的时候不能写 == t,而是要 >= t。
3、这题很容易T ,表示我T了N遍,弱菜啊。
Codes:
#include <cstdio> #include <iostream> #include <cstring> #include <cstdlib> #include <algorithm> #include <queue> using namespace std; int ns, ps, ts, te; int l=0x3f3f3f3f, r, Mid; struct Edge{ int from, to, dt; }e[40000 + 5]; struct Dinic{ static const int maxn = 300 + 5; static const int maxm = 80000 + 5; static const int oo = 0x3f3f3f3f; int n,m,s,t; int tot; int first[maxn],next[maxm]; int u[maxm],v[maxm],cap[maxm],flow[maxm]; int cur[maxn],dis[maxn]; bool vi[maxn]; Dinic(){tot=0;memset(first,-1,sizeof first);} void Clear(){tot = 0;memset(first,-1,sizeof first);} void Add(int from,int to,int cp,int flw){ u[tot] = from;v[tot] = to;cap[tot] = cp;flow[tot] = 0; next[tot] = first[u[tot]]; first[u[tot]] = tot; ++ tot; } bool bfs(){ memset(vi,false,sizeof vi); queue <int> q; dis[s] = 0;vi[s] = true; q.push(s); while(!q.empty()){ int now = q.front();q.pop(); for(int i = first[now];i != -1;i = next[i]){ if(!vi[v[i]] && cap[i] > flow[i]){ vi[v[i]] = true; dis[v[i]] = dis[now] + 1; q.push(v[i]); } } } return vi[t]; } int dfs(int x,int a){ if(x == t || a == 0) return a; int flw=0,f; int &i = cur[x]; for(i = first[x];i != -1;i = next[i]){ if(dis[x] + 1 == dis[v[i]] && (f = dfs(v[i],min(a,cap[i]-flow[i]))) > 0){ flow[i] += f;flow[i^1] -= f; a -= f;flw += f; if(a == 0) break; } } return flw; } int MaxFlow(int s,int t){ this->s = s;this->t = t; int flw=0; while(bfs()){ memset(cur,0,sizeof cur); flw += dfs(s,oo); } return flw; } }Net; bool check(int mid){ Net.Clear(); for(int i = 1; i <= ps; ++ i){ if(e[i].dt <= mid){ Net.Add(e[i].from, e[i].to, 1, 0); Net.Add(e[i].to, e[i].from, 1, 0); } } return Net.MaxFlow(1, Net.n) >= ts; } int Solve(){ int ans; while(l <= r){ Mid = l + (r - l) / 2; if(check(Mid)){ ans = Mid; r = Mid - 1; } else l = Mid + 1; } return ans; } int main(){ int x, y, z; scanf("%d%d%d", &ns, &ps, &ts); Net.n = ns;te = 0; for(int i = 1; i <= ps; ++ i){ scanf("%d%d%d", &x, &y, &z); ++ te; e[te].from = x;e[te].to = y;e[te].dt = z; l = min(l, z); r = max(z, r); } printf("%d\n", Solve()); return 0; }
POJ 2455 T 版
相关文章推荐
- DFileManager:封面流(CoverFlow)文件管理器
- 【震惊】百度推广网站被植入广告?这是善意还是恶意的?
- 后缀数组应用——多个字符串的相关问题
- [NOI2014]魔法森林|动态树
- python学习之socket创建html服务器
- 01课程介绍-DirectX游戏开发初级教程
- [leetcode] 61. Rotate List 解题报告
- LNMP一键安装包
- PHP的单态类——为了产生唯一的对象
- Docker实战(十一):Docker安装ELK环境(二)
- 经纬度转换成屏幕坐标
- 《软件需求》读书笔记3
- 《软件需求》读书笔记2
- 《软件需求》读书笔记1
- ios之"performSelector may cause a leak because its selector is unknown"警告原因及其解决办法
- Android笔记(七十四) 详解Intent
- *Reverse Words in a String II
- java:读写csv文件
- Android开发之常用Intent.Action【转】
- Object_c底层细节