[HDOJ5889]Barricade(spfa,最大流)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5889

求出所有最短路,标记好以后跑最大流就是最小割。

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 #define fr first
  4 #define sc second
  5 #define cl clear
  6 #define BUG puts("here!!!")
  7 #define W(a) while(a--)
  8 #define pb(a) push_back(a)
  9 #define Rint(a) scanf("%d", &a)
 10 #define Rll(a) scanf("%lld", &a)
 11 #define Rs(a) scanf("%s", a)
 12 #define Cin(a) cin >> a
 13 #define FRead() freopen("in", "r", stdin)
 14 #define FWrite() freopen("out", "w", stdout)
 15 #define Rep(i, len) for(int i = 0; i < (len); i++)
 16 #define For(i, a, len) for(int i = (a); i < (len); i++)
 17 #define Cls(a) memset((a), 0, sizeof(a))
 18 #define Clr(a, x) memset((a), (x), sizeof(a))
 19 #define Full(a) memset((a), 0x7f7f7f, sizeof(a))
 20 #define lrt rt << 1
 21 #define rrt rt << 1 | 1
 22 #define pi 3.14159265359
 23 #define RT return
 24 #define lowbit(x) x & (-x)
 25 #define onenum(x) __builtin_popcount(x)
 26 typedef long long LL;
 27 typedef long double LD;
 28 typedef unsigned long long ULL;
 29 typedef pair<int, int> pii;
 30 typedef pair<string, int> psi;
 31 typedef pair<LL, LL> pll;
 32 typedef map<string, int> msi;
 33 typedef vector<int> vi;
 34 typedef vector<LL> vl;
 35 typedef vector<vl> vvl;
 36 typedef vector<bool> vb;
 37
 38 const int maxn = 1100;
 39 const int maxm = 11000;
 40 const int inf = 1000000000;
 41 typedef struct Edge {
 42   int u, v, w;
 43   int next;
 44   Edge() { next = -1; }
 45 }Edge;
 46
 47 int n, m, s, t;
 48 Edge edge[maxm];
 49 int head[maxn], ecnt;
 50 int d[maxn];
 51 bool vis[maxn];
 52 int u, v, w;
 53
 54 int cnt, dhead[maxn];
 55 int cur[maxn], dd[maxn];
 56 Edge dedge[maxm];
 57 int S, T, N;
 58
 59 void adde(int u, int v, int w) {
 60   edge[ecnt].u = u; edge[ecnt].v = v; edge[ecnt].w = w;
 61   edge[ecnt].next = head[u]; head[u] = ecnt++;
 62 }
 63
 64 void init() {
 65   Clr(head, -1); ecnt = 0; Cls(vis);
 66   Cls(edge);
 67   Clr(dhead, -1); Cls(dedge);
 68     cnt = 0;
 69 }
 70
 71 void spfa(int s) {
 72   queue<int> q;
 73   Rep(i, n+1) d[i] = inf;
 74   d[s] = 0; q.push(s);
 75   vis[s] = 1;
 76   while(!q.empty()) {
 77     int u = q.front(); q.pop(); vis[u] = 0;
 78     for(int i = head[u]; ~i; i=edge[i].next) {
 79       int v = edge[i].v;
 80       if(d[v] > d[u] + 1) {
 81         d[v] = d[u] + 1;
 82         if(!vis[v]) {
 83           vis[v] = 1;
 84           q.push(v);
 85         }
 86       }
 87     }
 88   }
 89 }
 90
 91 void dadde(int u, int v, int w, int c1) {
 92     dedge[cnt].u = u; dedge[cnt].v = v; dedge[cnt].w = w;
 93     dedge[cnt].next = dhead[u]; dhead[u] = cnt++;
 94     dedge[cnt].u = v; dedge[cnt].v = u; dedge[cnt].w = c1;
 95     dedge[cnt].next = dhead[v]; dhead[v] = cnt++;
 96 }
 97
 98 bool bfs(int s, int t, int n) {
 99     queue<int> q;
100     for(int i = 0; i < n; i++) dd[i] = inf;
101     dd[s] = 0;
102     q.push(s);
103     while(!q.empty()) {
104         int u = q.front(); q.pop();
105         for(int i = dhead[u]; ~i; i = dedge[i].next) {
106             if(dd[dedge[i].v] > dd[u] + 1 && dedge[i].w > 0) {
107                 dd[dedge[i].v] = dd[u] + 1;
108                 if(dedge[i].v == t) return 1;
109                 q.push(dedge[i].v);
110             }
111         }
112     }
113     return 0;
114 }
115
116 int dinic(int s, int t, int n) {
117     int st[maxn], top;
118     int u;
119     int flow = 0;
120     while(bfs(s, t, n)) {
121         for(int i = 0; i < n; i++) cur[i] = dhead[i];
122         u = s; top = 0;
123         while(cur[s] != -1) {
124             if(u == t) {
125                 int tp = inf;
126                 for(int i = top - 1; i >= 0; i--) {
127                     tp = min(tp, dedge[st[i]].w);
128                 }
129                 flow += tp;
130                 for(int i = top - 1; i >= 0; i--) {
131                     dedge[st[i]].w -= tp;
132                     dedge[st[i] ^ 1].w += tp;
133                     if(dedge[st[i]].w == 0) top = i;
134                 }
135                 u = dedge[st[top]].u;
136             }
137             else if(cur[u] != -1 && dedge[cur[u]].w > 0 && dd[u] + 1 == dd[dedge[cur[u]].v]) {
138                 st[top++] = cur[u];
139                 u = dedge[cur[u]].v;
140             }
141             else {
142                 while(u != s && cur[u] == -1) {
143                     u = dedge[st[--top]].u;
144                 }
145                 cur[u] = dedge[cur[u]].next;
146             }
147         }
148     }
149     return flow;
150 }
151
152 signed main() {
153   //FRead();
154   int ttt;
155   Rint(ttt);
156   W(ttt) {
157     init();
158     Rint(n); Rint(m);
159     Rep(i, m) {
160       Rint(u); Rint(v); Rint(w);
161       adde(u,v,w); adde(v,u,w);
162     }
163     spfa(1);
164     Rep(i, ecmt) {
165       if(d[edge[i].v] == d[edge[i].u] + 1) {
166         dadde(edge[i].u-1, edge[i].v-1, edge[i].w, 0);
167       }
168     }
169     S = 0; T = n - 1; N = n;
170     printf("%d\n", dinic(S, T, N));
171   }
172   RT 0;
173 }
时间: 2024-10-23 09:32:05

[HDOJ5889]Barricade(spfa,最大流)的相关文章

bzoj 2285 [Sdoi2011]保密(二分,spfa + 最大流)

Description 现在,保密成为一个很重要也很困难的问题.如果没有做好,后果是严重的.比如,有个人没有自己去修电脑,又没有拆硬盘,后来的事大家都知道了. 当然,对保密最需求的当然是军方,其次才是像那个人.为了应付现在天上飞来飞去的卫星,军事基地一般都会建造在地下. 某K国的军事基地是这样子的:地面上两排大天井共n1个作为出入口,内部是许多除可以共享出入口外互不连通的空腔,每个空腔有且只有两个出入口,并且这两个出入口不会在同一排.为了方便起见,两排出入口分别编号为1,3,5…和2,4,6…并

HDU 3416 Marriage Match IV(spfa+最大流)

题目的大体意思是:给你一些有向边让你求出给出的点s,t之间最短路的条数. 两边spfa从s到t,和从t到s然后求出在最短路上的点建一条容量为1的边,然后求出s到t的最大的流量,就是最短路的数目. PS:代码写的姿势不够优美. Marriage Match IV Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2051    Accept

HDU3416 Marriage Match IV(spfa+最大流SAP)

Marriage Match IV Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2391    Accepted Submission(s): 722 Problem Description Do not sincere non-interference. Like that show, now starvae also take

Spfa费用流模板

1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <queue> 5 using namespace std; 6 const int INF=233333333; 7 const int maxn=1010,maxm=40010; 8 int cnt,fir[maxn],nxt[maxm],to[maxm],cap[maxm],val[maxm],dis[ma

[BZOJ3931][CQOI2015]网络吞吐量(spfa+最大流)

题目描述 传送门 题解 求出最短路径图之后拆点跑最大流. 判断一条边在最短路图上:dis[edge[i].x]+redis[edge[i].y]+edge[i].w==dis[n]或dis[edge[i].y]+redis[edge[i].x]+edge[i].w==dis[n],其中dis和redis都是单源最短路,源分别为1和n 代码 #include<algorithm> #include<iostream> #include<cstring> #include&

POJ2195 Going Home[费用流|二分图最大权匹配]

Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22088   Accepted: 11155 Description On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, either horizontally, or vertica

CF 277E Binary Tree on Plane (拆点 + 费用流) (KM也可做)

题目大意: 平面上有n个点,两两不同.现在给出二叉树的定义,要求树边一定是从上指向下,即从y坐标大的点指向小的点,并且每个结点至多有两个儿子.现在让你求给出的这些点是否能构成一棵二叉树,如果能,使二叉树的树边长度(欧几里德长度)总和最小,输出这个总和.如果不能,输出-1.答案与标准答案相差1e-6内都认为是正确的. 算法讨论: 起初是这样想的,肯定是MCMF,费用是距离,然后流量一开始我是这样搞的:从父亲向儿子连流量为2的边.但是你会发现这样有一个问题,就是如果某个结点如果真的有两个儿子的话,那

【bzoj4276】[ONTAK2015]Bajtman i Okr?g?y Robin 线段树优化建图+费用流

题目描述 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2],...,[b[i]-1,b[i]]这么多段长度为1时间中选出一个时间进行抢劫,并计划抢走c[i]元.作为保安,你在每一段长度为1的时间内最多只能制止一个强盗,那么你最多可以挽回多少损失呢? 输入 第一行包含一个正整数n(1<=n<=5000),表示强盗的个数. 接下来n行,每行包含三个正整数a[i],b[i],c[i](1<=a[i]<b[i]<=5000,1<=c[i]

【Tyvj1982】武器分配(费用流)

题意:有N个人要从A个物品中各取一个,B个物品中各取一个,选取第i个A类物品和第j个B类物品的费用是(a[i]-b[j])^2 求最小总花费 n<=a,b<=80 a[i],b[i]<=10000 思路:第一题费用流 由源点到每个A类物品连容量为1,费用为0的边 每个B类物品到第一个汇点连容量为1,费用为0的边 对于ai和bj连容量为1,费用为(a[i]-b[j])^2的边 因为只需要N对物品,由第一个汇点到第二个汇点连容量为N,费用为0的边来限制流量上限 答案就是从源点到第二个汇点流量