BZOJ4435——[Cerc2015]Juice Junctions
来源:互联网 发布:vb计算圆的面积和周长 编辑:程序博客网 时间:2024/05/20 08:21
0、题目大意:求两点之间的最小割之和
1、分析:很明显,最小割树,我们发现这个题并不能用n^3的方法来求答案。。
所以我们记录下所有的边,然后把边从大到小排序,然后跑一边类似kruskal的东西,顺便统计答案
TAT,这个题我被卡常数了,贴上TLE的代码吧。。。
#include <queue>#include <ctime>#include <cstdio>#include <cstring>#include <cstring>#include <algorithm>using namespace std;#define LL long long#define inf 214748364 struct Edge{ int from, to, cap, flow, next;};int head[3010], cur[3010];Edge G[20010];int tot;int d[3010];bool vis[3010];int s, t, n, m;int a[3010];int b[3010]; inline void init(){ memset(head, -1, sizeof(head)); tot = -1; return;} inline void insert(int from, int to, int cap){ G[++ tot] = (Edge){from, to, cap, 0, head[from]}; head[from] = tot; G[++ tot] = (Edge){to, from, 0, 0, head[to]}; head[to] = tot; return;} inline bool BFS(){ for(int i = 1; i <= n; i ++) vis[i] = 0; queue<int> Q; Q.push(s); vis[s]=1; d[s]=0; while(!Q.empty()){ int x = Q.front(); Q.pop(); for(int i = head[x]; i != -1; i = G[i].next){ Edge& e = G[i]; if(e.cap - e.flow > 0 && !vis[e.to]){ vis[e.to] = 1; d[e.to]=d[x]+1; Q.push(e.to); } } } return vis[t];} inline int dfs(int x, int a){ if(x == t || a == 0) return a; int flow = 0, f; for(int& i = cur[x]; i != -1; i = G[i].next){ Edge& e = G[i]; if(d[x]+1 == d[e.to] && (f = dfs(e.to, min(e.cap - e.flow, a))) > 0){ e.flow += f; G[i ^ 1].flow -= f; flow += f; a -= f; if(a == 0) break; } } return flow;} inline int maxflow(){ int res = 0; while(BFS()){ for(int i = 1; i <= n; i ++) cur[i] = head[i]; res += dfs(s, inf); } return res;} inline void Clear(){ for(int i = 0; i <= tot; i += 2){ G[i].flow = G[i ^ 1].flow = (G[i].flow + G[i ^ 1].flow) / 2; }} struct node{ int u, v, w; inline bool operator < (const node& rhs) const{ return w > rhs.w; }} T[20010];int num; inline void add(int u, int v, int w){ T[++ num].u = u; T[num].v = v; T[num].w = w;} inline void solve(int l, int r){ if(l == r) return; int rl = rand() % (r - l + 1) + l; int rr = rand() % (r - l + 1) + l; if(rl == rr) rl ++; if(rl > r) rl -= 2; s = a[rl], t = a[rr]; Clear(); int tw = maxflow(); //puts("fuck"); add(a[rl], a[rr], tw); int L = l, R = r; for(int i = l; i <= r; i ++){ if(vis[a[i]]) b[L ++] = a[i]; else b[R --] = a[i]; } for(int i = l; i <= r; i ++) a[i] = b[i]; solve(l, L - 1); solve(L, r);} int ff[20010], size[20010]; inline int find(int x){ return ff[x] == x ? x : ff[x] = find(ff[x]);} int main(){ // srand(time(NULL)); scanf("%d%d", &n, &m); init(); for(int i = 1; i <= m; i ++){ int u, v; scanf("%d%d", &u, &v); insert(u, v, 1); insert(v, u, 1); } for(int i = 1; i <= n; i ++) a[i] = i; solve(1, n); LL ret = 0; sort(T + 1, T + num + 1); for(int i = 1; i <= n; i ++) size[i] = 1, ff[i] = i; // puts("fuck"); for(int i = 1; i <= num; i ++){ int tx = find(T[i].u), ty = find(T[i].v); if(size[tx] < size[ty]) swap(tx, ty); ret += (LL)T[i].w * size[tx] * size[ty]; ff[ty] = tx; size[tx] += size[ty]; } printf("%lld\n", ret); return 0;}
0 0
- BZOJ4435——[Cerc2015]Juice Junctions
- 【CERC2015】【BZOJ4435】Juice Junctions
- BZOJ 4435: [Cerc2015]Juice Junctions tarjan
- [边双连通分量 Hash] BZOJ 4435 [Cerc2015]Juice Junctions
- Juice
- Juice
- Lightoj1216——Juice in the Glass (计算几何)
- 【bzoj4421】【cerc2015】【Digit Division】
- 【CERC2015】【BZOJ4432】Greenhouse Growth
- 【CERC2015】【BZOJ4434】Ice Igloos
- BZOJ4436 [Cerc2015]Kernel Knights
- zstu4119 Juice树形dp
- NCPC 2012 Juice(练习)
- ZSTU 4119 Juice
- uva 12018 Juice Extractor
- ural 2071 - Juice Cocktails
- UVa12018 Juice Extractor ( DP )
- Juice Extractor dp
- 《Linux命令行大全》学习笔记
- 寄存 【GDOI 2016 Day2】第一题 SigemaGO
- 一些很有用的小函数(自己写的)
- 莱文斯坦距离计算字符串的相似度
- 常用的正则表达式
- BZOJ4435——[Cerc2015]Juice Junctions
- Microsoft SQL Server 数据库的子查询运算分析
- android view 的requestLayout和invalidate
- CSS背景属性
- 检测文件类型的另外一种思路
- HTML网页编程
- Retrofit – Java(Android) 的REST 接口封装类库
- c++通过指针实现队列
- C++ opencv 读取mp4文件