题解 CF852D Exploration plan

技术题解 CF852D Exploration plan 题解 CF852D Exploration plan【题意翻译】
给定一个\(V\) 个点\(E\) 条边的带权无向图,在图上有\(N\) 个人

题解CF852D勘探计划

【题意翻译】

给定一个\(五\)个点\(E\)条边的带权无向图,在图上有\(N\)个人,第\(i\)个人位于点\(x_

i\),一个人通过一条边需要花费这条边的边权的时间。

现在每个人可以自由地走。求最短多少时间后满足结束后有人的节点数\(\geq K\)

\(N,V \leq 500\)

【题目分析】

首先发现V很小,直接用\(弗洛伊德\)跑一遍全源最短路径。

然后考虑如何求时间,这个其实是图论中一个很经典的二分图论的模型,那么我们可以用一个二分寻找\(中\),连上所有长度\(\leq mid\)的边,用图论来\(检查\).

接下来就要选择图论使用的模型了。在一个图上,有一些人从一个点走向另一个点,很容易想到网络流中的最大流。由于每个点只要有人就行,那么让每个点向超级汇点\(t\)连一条容量为\(1\)的边,代表这个点对答案能产生\(1\)的流量,从超级源点\(s\)向每个点连一条容量为这个点人数的边,代表这个点能流出等同于这个点人数的流量,然后将\(\leq mid\)的边作为网络中的一条边,容量为\(inf\),跑最大流,判断是否\(\geq K\)。

\(tips:\)

建图的时候要拆点,拆成入口和出口,不然会出现流量分配的问题

每次支票记得记忆集

重边要取最小值

愉快的贴代码时间

#包括ebit/stdc .h

#定义inf 1e15

使用命名空间标准;

int read(){ 0

int w=0,h=1;char ch=getchar();

while(ch ' 0 ' | | ch ' 9 '){ if(ch=='-')h=-h;ch=getchar();}

while(ch=' 0 ' ch=' 9 '){ w=w * 10 ch-' 0 ';ch=getchar();}

返回w * h;

}

整数n,m,s,t,K,cnt,和;

int cow[610],谷仓[610];

int Floyd[610][610];

struct Dinic{

结构节点{

int旁边,cap,flow

} edge[3000010];

int head[10010],num

int cur[10010];

int dist[10010];

queueintq

void add(int u,int v,int cap,int flow){ 0

边[数]。next=head[u];

边[数]。to=v;

边[数]。cap=cap

边[数]。流量=流量;

head[u]=num;

返回;

}

void Add(int u,int v,int cap){ 0

add(u,v,cap,0);

add(v,u,0,0);

返回;

}

bool bfs(){ 0

memset(dist,0,sizeof(dist));

dist[s]=1;

q .推送;

while(!q . empty()){ 0

int u=q . front();

q . pop();

for(int I=head[u];我;i=edge[i].下一个){ 0

int v=edge[i].去;

if(!距离[v]边缘[i].卡佩治[我]。流量){ 0

dist[v]=dist[u]1;

q . push(v);

}

}

}

return dist[t];

}

int dfs(int u,int flow){ 0

if(u==t)回流;

int fl=0;

for(int I=cur[u];我;i=edge[i].下一个){ 0

cur[u]=I;

int v=edge[i].去;

if(dist[u] 1==dist[v]edge[i].卡佩治[我]。流量){ 0

int p=dfs(v,min(流量,边缘[i]).帽沿。流量));

if(p){ 0

边缘。流量=p;

edge[i^1].流量-=p;

流量-=p;

fl=p;

if(!流动)中断;

}

}

}

if(!fl)dist[u]=0;

返回fl;

}

int solve(){ 0

int flow=0;

while(bfs()){ 0

memcpy(cur,head,sizeof(cur));

int p;

而(p=dfs(s,1e9))流量=p;

}

回流;

}

void memst(){ 0

memset(head,0,sizeof(head));

num=1;

}

布尔检查(int x){ 0

memst();

for(int I=1;I=n;一)增加(1个n,t,1);

for(int I=1;I=n;I){ 0

如果(牛[i])加(s,I,牛[I]);

for(int j=1;j=n;j)

如果(弗洛伊德[i][j]=x)

添加(I,j n,1e 9);

}

返回求解()=K;

}

} ans

签名main(){ 0

n=read();m=read();CNT=read();k=read();

s=0;t=n n ^ 2;

memset(floyd,0x3f,sizeof(Floyd));

for(int I=1;i=cntI)奶牛[read()];

for(int I=1;I=n;(一)弗洛伊德[I][I]=0;

for(int I=1;I=m;I){ 0

int u=read(),v=read(),w=read();

弗洛伊德[u][v]=弗洛伊德[v][u]=min(弗洛伊德[u][v],w);

}

for(int k=1;k=n;k)

for(int I=1;I=n;(一)

for(int j=1;j=n;j)

弗洛伊德[I][j]=最小值(弗洛伊德[i][j],弗洛伊德[i][k]弗洛伊德[k][j]);

int l=0,r=1731311,RES=-1;

while(l=r){ 0

int mid=l r1

if(ans.check(mid))r=mid-1,res=mid

否则l=mid 1;

}

printf('%d\n ',RES);

返回0;

}

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/67469.html

(0)

相关推荐

  • CSS中解决div列高度自适应的3种常用方法分别是什么

    技术CSS中解决div列高度自适应的3种常用方法分别是什么CSS中解决div列高度自适应的3种常用方法分别是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的

    攻略 2021年11月2日
  • Java处理Exception的方法有哪些

    技术Java处理Exception的方法有哪些这篇文章主要讲解了“Java处理Exception的方法有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java处理Ex

    攻略 2021年11月30日
  • 操作系统是一套什么程序的集合

    技术操作系统是一套什么程序的集合本篇内容介绍了“操作系统是一套什么程序的集合”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成

    攻略 2021年11月8日
  • bytes最大值(数据类型的字节大小)

    技术为什么bytes的值比maxbytes的值要大这篇文章主要讲解了“为什么bytes的值比maxbytes的值要大”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“为什么b

    攻略 2021年12月22日
  • 粘鼠板的胶简单去除法,毛刷粘上粘鼠板胶怎么去除

    技术粘鼠板的胶简单去除法,毛刷粘上粘鼠板胶怎么去除1风油精去胶法首先将风油精滴在湿巾纸上,然后用被风油精打湿的湿巾纸擦拭沾有粘鼠板的胶的地方,进行多次擦拭,顽固的残胶会慢慢的变软,最后就会去掉粘鼠板的胶简单去除法。2酒精

    生活 2021年10月29日
  • 过去的日子如什么仿写,匆匆第4段的仿写急!在线等

    技术过去的日子如什么仿写,匆匆第4段的仿写急!在线等1过去的日子如什么仿写、过去的日子如一块巧克力,不久就在嘴里化了;如一滴水,在阳光的照耀下蒸发了;
    如一个细胞,很快就死去了;如一片雪花,被阳光照化了。
    2、在这烟花缤

    生活 2021年10月25日