HDU 5294 Tricks Device 最短路+最小割
来源:互联网 发布:js 箭头函数作用域 编辑:程序博客网 时间:2024/05/22 17:20
题意:给你一个无向图 问你 至少和至多 删除多少条边 可以使从起点到终点的最短路变长(并不一定不可到达)
思路:比赛的时候想的方法是费用流+二分 无限超时 水的不行- - 正解是先用最短路预处理出所有的最短路径 建图后求最小割即为至少删除的边数 因为删除了最小割上的边 最短路上的起点和终点就不连通了 放在原图上最短路必然增大 而原图所有边数减去最短路径上边数最少的那条路径的值就是至多删除的边数 代码写得很糟乱 懂了思想就好。。
#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std;#define REP( i, a, b ) for( int i = a; i < b; i++ )#define FOR( i, a, b ) for( int i = a; i <= b; i++ )#define CLR( a, x ) memset( a, x, sizeof a )#define CPY( a, x ) memcpy( a, x, sizeof a )const int maxn = 2000 + 10;const int maxe = 240000 + 10;const int INF = 1e9;struct Edge{ int v, c, f; int next; Edge() {} Edge(int v, int c, int f, int next) : v(v), c(c), f(f), next(next) {}};struct ISAP{ int n, s, t; int num[maxn], cur[maxn], d[maxn], p[maxn]; int Head[maxn], cntE; int Q[maxn], head, tail; Edge edge[maxe]; void Init(int n){ this -> n = n; cntE = 0; CLR(Head, -1); } void Add(int u, int v, int c){ edge[cntE] = Edge(v, c, 0, Head[u]); Head[u] = cntE++; edge[cntE] = Edge(u, 0, 0, Head[v]); Head[v] = cntE++; } void Bfs(){ CLR(d, -1); CLR(num, 0); d[t] = 0; head = tail = 0; Q[tail++] = t; num[0] = 1; while(head != tail){ int u = Q[head++]; for(int i = Head[u]; ~i; i = edge[i].next){ Edge &e = edge[i]; if(~d[e.v]) continue; d[e.v] = d[u] + 1; Q[tail++] = e.v; num[d[e.v]] ++; } } } int Maxflow(int s, int t){ this -> s = s; this -> t = t; CPY(cur, Head); Bfs(); int flow = 0, u = p[s] = s; while(d[s] < n){ if(u == t){ int f = INF, neck; for(int i = s; i != t; i = edge[cur[i]].v){ if(f > edge[cur[i]].c - edge[cur[i]].f){ f = edge[cur[i]].c - edge[cur[i]].f; neck = i; } } for(int i = s; i != t; i = edge[cur[i]].v){ edge[cur[i]].f += f; edge[cur[i]^1].f -= f; } flow += f; u = neck; } int ok = 0; for(int i = cur[u]; ~i; i = edge[i].next){ Edge &e = edge[i]; if(e.c > e.f && d[e.v] + 1 == d[u]){ ok = 1; cur[u] = i; p[e.v] = u; u = e.v; break; } } if(!ok){ int m = n - 1; if(--num[d[u]] == 0) break; for(int i = Head[u]; ~i; i = edge[i].next){ Edge &e = edge[i]; if(e.c - e.f > 0 && m > d[e.v]){ cur[u] = i; m = d[e.v]; } } ++num[d[u] = m + 1]; u = p[u]; } } return flow; }}solver;struct SPFA{ int top, cntE, n; int Head[maxn], vis[maxn], cnt[maxn], STACK[maxn], dist[maxn]; Edge edge[maxe]; void init(int n){ this -> n = n; CLR(Head, -1); CLR(vis, 0); cntE = top = 0; } void add(int u, int v, int d){ edge[cntE] = Edge(v, d, 0, Head[u]); Head[u] = cntE++; } bool spfa(int s){ CLR(vis, 0); CLR(cnt, 0); vis[s] = cnt[s] = 1; STACK[top++] = s; REP(i, 0, n) dist[i] = INF; dist[s] = 0; while(top){ int u = STACK[--top]; vis[u] = 0; for(int i = Head[u]; ~i; i = edge[i].next){ int v = edge[i].v; if(dist[v] > dist[u] + edge[i].c){ dist[v] = dist[u] + edge[i].c; if(!vis[v]){ vis[v] = 1; STACK[top++] = v; if(++cnt[v] > n) return false; } } } } return true; }}Spfa, Spfa2;int n, m;int vis[maxn];void bfs(){ memset(vis, 0, sizeof(vis)); vis[n-1] = 1; queue<int> Q; Q.push(n-1); while(!Q.empty()){ int u = Q.front(); Q.pop(); for(int i = Spfa.Head[u]; ~i; i = Spfa.edge[i].next){ int v = Spfa.edge[i].v; if(Spfa.dist[v] + Spfa.edge[i].c == Spfa.dist[u]){ solver.Add(u, v, 1); Spfa2.add(u, v, 1);// printf(".. %d %d\n", u+1, v+1); if(!vis[v]) Q.push(v); vis[v] = 1; } } } Spfa2.spfa(n-1); printf("%d %d\n", solver.Maxflow(n-1, 0), m - Spfa2.dist[0]);}void solve(){ Spfa.init(n); Spfa2.init(n); solver.Init(n); REP(i, 0, m){ int u, v, d; scanf("%d%d%d", &u, &v, &d); --u; --v; Spfa.add(u, v, d); Spfa.add(v, u, d); } Spfa.spfa(0); bfs();}int main(){// freopen("in.txt", "r", stdin); while(~scanf("%d%d", &n, &m)) solve(); return 0;}
0 0
- hdu HDU 5294 - Tricks Device(最短路+最小割)
- HDU 5294 - Tricks Device(最短路+最小割)
- hdu 5294 Tricks Device 最短路建图+最小割
- HDU 5294 Tricks Device(最短路+最小割)
- HDU 5294 Tricks Device 最短路+最小割
- HDU 5294(Tricks Device-最短路最小割)[Template:SPFA]
- HDU 5294 Tricks Device(最短路最小割)
- HDU 5294 Tricks Device 最短路最小割 -
- hdu5294 Tricks Device 最短路+最小割
- HDOJ 5294 Tricks Device 最短路(记录路径)+最小割
- hdoj 5294 Tricks Device 【最短路+ 最小割】
- 【hdoj 5294】 Tricks Device 【最小割+最短路spfa】
- HDU 5294 Tricks Device(2015多校第一场 最短路 + 最小割)
- HDU 5294 Tricks Device (最短路上的最小割) 2015多校训练1007
- HDU 5294--Tricks Device【最小割 && 最短路处理,新建图】
- hdu 5294 Tricks Device(最短路+网络流(最小割))
- HDU 5294 Tricks Device (2015 MUT#1 最短路建图+最小割)
- HDU 5294 Tricks Device 最短路建图+最小割(最大流)
- Android Retrofit 2.0的基本使用
- leetCode 104.Maximum Depth of Binary Tree(二叉树最大深度) 解题思路和方法
- 【NOIP2007】矩阵取数题解
- UE4学习笔记12th
- TCP协议详解(一)
- HDU 5294 Tricks Device 最短路+最小割
- C语言:非减链表的合并
- HahMap 与 ConcurrentHashMap 对比
- HDU 2191 多重背包问题
- leetCode 105.Construct Binary Tree from Preorder and Inorder Traversal (根据前序遍历和中序遍历构造二叉树)
- DEX 方法超过64K限制和gradle编译OOM问题解决
- acm-uva10653解题报告
- cygwin不能执行make
- 设计模式之Factory----经典