题目链接

luogu P1401 城市

题解

二分最小边权,dinic检验

代码

// luogu-judger-enable-o2
/*
二分最小边权,dinic检验
*/
#include<queue>
#include<cctype>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
inline int read() {
int x = 0,f = 1;
char c = getchar();
while(c < '0' || c > '9'){if(c == '-')f =- 1 , c = getchar(); }
while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar();
return x * f;
}
#define INF 1e9 + 7
const int maxn = 40007;
struct node {
int u,v,w,next;
bool operator < (const node & a) const {
return w < a.w;
}
} e[maxn];
int head[maxn],num = 1;
struct Node {
int v,flow,next;
} edge[maxn << 2];
inline void add_edge(int u,int v,int flow ) {
edge[++ num].v = v;edge[num].next = head[u];head[u] = num; edge[num].flow = flow;
edge[++ num].v = u;edge[num].next = head[v];head[v] = num; edge[num].flow = flow;
}
int cur[maxn];
int S = 1,T ;
int n,m,t;
std::queue<int>q;
int lev[maxn];
bool bfs() {
for(int i = 0;i <= n;++ i) cur[i] = head[i];
for(int i = 0;i <= n;++ i) lev[i] = -1;
q.push(S),lev[S] = 0;
while(!q.empty()) {
int u = q.front(); q.pop();
for(int i = head[u];i;i = edge[i].next)
if(edge[i].flow > 0 && lev[edge[i].v] == -1) lev[edge[i].v] = lev[u] + 1,q.push(edge[i].v);
}
return lev[T] != -1;
}
int dfs(int now,int flow) {
if(now == T) return flow;
int rest = 0 , delta;
for(int &i = cur[now];i;i = edge[i].next) {
int v = edge[i].v;
if(lev[v] != lev[now] + 1 || edge[i].flow <= 0) continue;
delta = dfs(v,std::min(flow - rest,edge[i].flow));
if(delta) {
edge[i].flow -= delta;
edge[i ^ 1].flow += delta;
rest += delta; if(rest == flow) break;
}
}
if(rest == flow) lev[now] = -1;
return rest;
}
int dinic() {
int ret = 0;
while(bfs()) ret += dfs(S,INF);
return ret;
}
bool check(int x) {
num = 1;
memset(head,0,sizeof head);
for(int i = 1;i <= m;++ i)
if(e[i].w <= x) add_edge(e[i].u,e[i].v,1);
else break;
return dinic() >= t;
}
int main() {
n = read(),m = read(),t = read(); T = n;
for(int i = 1;i <= m;++ i) e[i].u = read(), e[i].v = read(),e[i].w = read();
std::sort(e + 1, e + m + 1);
int l = 0,r = 100000007;
int ans = -1;
while(l <= r) {
int mid = l + r >> 1;
if(check(mid)) ans = mid , r = mid - 1;
else l = mid + 1;
}
printf("%d\n",ans);
return 0;
}

最新文章

  1. php实现中文转数字,实现方式很智能很php
  2. Epub基础知识介绍
  3. 远程重装centos6
  4. json数组转数组对象
  5. php 数据库备份、还原
  6. 批量部署ssh信任关系
  7. BZOJ3994: [SDOI2015]约数个数和
  8. JMS之开源实现ActiveMQ
  9. linux gcc 和 g++ 编译
  10. HW5.16
  11. 一句话输出网站404页面,REFER及相关排序
  12. js中document.write()使用方法
  13. cshtml一二
  14. Hadoop2.41的HA的配置与启动
  15. java中常用的进制转换
  16. Unity3D学习笔记(二十六):MVC框架下的背包系统(1)
  17. Allocation-Free Collections
  18. UML类图和时序图
  19. Java方法containsAll学习
  20. ubuntu 的chmod 和 chown

热门文章

  1. vue axios的使用
  2. javaweb购物车实现的几种方式
  3. Confluence wiki——CentOS6.8搭建详解
  4. bzoj千题计划284:bzoj2882: 工艺
  5. Jerasure库简介及使用范例
  6. websocket知识简单总结!
  7. android ViewPager之PagerAdapter中View的重用
  8. Java初转型-SSM配置文件
  9. 春夏秋冬又一春之Redis持久化
  10. linux sftp安装【转】