【HDU 5889】Barricade(最短路+最小割)
来源:互联网 发布:编程好看的字体 编辑:程序博客网 时间:2024/06/10 14:43
【HDU 5889】Barricade(最短路+最小割)
题目大意:
n点m边无向图,1为己方 n为敌方
每条边有建阻碍的花费 距离都是1
已知敌方会选择最短路来己方。要选择一些路设障碍,让敌方至少碰到一个障碍。
先跑一个最短路。
对于每条边
这条路就可能在最短路中。
然后跑个最小割(其实就是最大流)
为什么酱紫保证正确呢?赛后我也有怀疑是水数据。。
后来金巨一句点醒梦中人。。
如果不是最短路中的边,肯定无法跑到终点,至少会有一处断开。所以大胆跑最小割就行了
代码如下:
#include <iostream>#include <cmath>#include <vector>#include <cstdlib>#include <cstdio>#include <climits>#include <ctime>#include <cstring>#include <queue>#include <stack>#include <list>#include <algorithm>#include <map>#include <set>#define LL long long#define Pr pair<int,int>#define fread(ch) freopen(ch,"r",stdin)#define fwrite(ch) freopen(ch,"w",stdout)using namespace std;const int INF = 0x3f3f3f3f;const int mod = 1e9+7;const double eps = 1e-8;const int maxn = 1111,maxm = 11111;struct Edge{ int v,w,next;} eg[maxm*5],teg[maxm*5];int ds[maxn];bool vis[maxn];int head[maxn],thead[maxn];int n,tp,ttp,st,en;void Add(int u,int v,int w){ eg[tp].v = v; eg[tp].w = w; eg[tp].next = head[u]; head[u] = tp++; eg[tp].v = u; eg[tp].w = 0; eg[tp].next = head[v]; head[v] = tp++;}void add(int u,int v,int w){ teg[ttp].v = v; teg[ttp].w = w; teg[ttp].next = thead[u]; thead[u] = ttp++;}int dis[maxn];int gap[maxn];int pre[maxn];int cur[maxn];int isap(){ memset(dis,0,sizeof(dis)); memset(gap,0,sizeof(gap)); memset(pre,-1,sizeof(pre)); memset(cur,-1,sizeof(cur)); gap[0] = n; int u,v,flow,ans; flow = INF; u = pre[0] = 0; ans = 0; while(dis[1] < en) { for(int &i = cur[u]; i != -1; i = eg[i].next) { if(eg[i].w && dis[eg[i].v]+1 == dis[u]) break; } if(cur[u] != -1) { v = eg[cur[u]].v; flow = min(flow,eg[cur[u]].w); pre[v] = u; u = v; if(u == en) { for(; u != 0; u = pre[u]) { eg[cur[pre[u]]].w -= flow; eg[cur[pre[u]]^1].w += flow; } ans += flow; flow = INF; } } else { int mn = n; for(int i = head[u]; i != -1; i = eg[i].next) { if(eg[i].w && dis[eg[i].v] < mn) { mn = dis[eg[i].v]; cur[u] = i; } } if(!(--gap[dis[u]])) break; dis[u] = mn+1; gap[dis[u]]++; u = pre[u]; } } return ans;}void bfs(){ queue <int> q; memset(vis,0,sizeof(vis)); memset(ds,INF,sizeof(ds)); ds[0] = 0; q.push(0); int u,v; while(!q.empty()) { u = q.front(); q.pop(); vis[u] = 0; for(int i = thead[u]; i != -1; i = teg[i].next) { v = teg[i].v; if(ds[v] > ds[u]+1) { ds[v] = ds[u]+1; if(!vis[v]) { q.push(v); vis[v] = 1; } } } }}int main(){ //fread(); //fwrite(); int t; int m; int u,v,w; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); memset(thead,-1,sizeof(thead)); tp = ttp = 0; st = 0,en = n-1; for(int i = 0; i < m; ++i) { scanf("%d%d%d",&u,&v,&w); u--,v--; add(u,v,w); add(v,u,w); } bfs(); for(int i = 0; i < n; ++i) { for(int j = thead[i]; j != -1; j = teg[j].next) { u = i; v = teg[j].v; if(ds[v] == ds[u]+1) { //printf("%d %d\n",u,v); Add(u,v,teg[j].w); } } } printf("%d\n",isap()); } return 0;}
0 0
- HDU 5889 Barricade(最短路最小割)
- HDU 5889 Barricade(最短路+最小割)
- hdu 5889 Barricade 最短路+最小割
- HDU 5889 Barricade 最短路最小割 -
- HDU 5889 Barricade 最短路+最小割
- [HDU 5889] Barricade (最短路 + 最小割)
- 【HDU 5889】Barricade(最短路+最小割)
- hdu 5889 Barricade (最短路+最小割)
- hdu 5889 Barricade (最短路的最小割)
- HDU-5889 Barricade(最小割或最短路+最小割)
- hdu 5889 Barricade【最短路SPFA+最小割--------Dinic】
- 【HDU5889】Barricade(最短路+最小割)
- 2016 ACM/ICPC Asia Regional Qingdao Online hdu 5889 Barricade (最短路+最小割)
- hdu5889 Barricade 最短路 + 最小割
- hdu 5889 Barricade【最小割】
- HDU 5889 Barricade(最小割)
- HDU 5889 Barricade 最小割
- HDU 5889 Barricade (单源最短路 + 最小割(最大流))
- Linux(6)RedHat7 基本命令五-hwclock(clock)命令详解
- 【Bash百宝箱】shell内建命令之冒号
- 在代码中写view 的长宽高等
- 如何调用TUIO中的源码
- 在ubuntu中安装Samba服务器
- 【HDU 5889】Barricade(最短路+最小割)
- RadioButton单选按钮
- 【Bash百宝箱】shell内建命令之句点与source
- Hibernate的批量处理
- jquery中常用方法
- qt5.6.1+mingw492+opencv2.4.10+cmake3.4.1配置
- shell中的条件判断与控制流程
- 198. House Robber
- 透视投影的原理和实现