2015多校联合训练第一场Tricks Device(hdu5294)
2017-07-04 08:14
281 查看
题意:给一个无向图,给起点s,终点t,求最少拆掉几条边使得s到不了t,最多拆几条边使得s能到t
思路:
先跑一边最短路,记录最短路中最短的边数。总边数-最短边数就是第二个答案
第一个答案就是在最短路里面求最小割,也就是求最大流,然后依据最短路在建个新图。权为1。跑一边网络流
模板题。以后就用这套模板了
思路:
先跑一边最短路,记录最短路中最短的边数。总边数-最短边数就是第二个答案
第一个答案就是在最短路里面求最小割,也就是求最大流,然后依据最短路在建个新图。权为1。跑一边网络流
模板题。以后就用这套模板了
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <vector> using namespace std; const int INF = 0x7f7f7f; const int MAXM = 12e4+5; const int MAXN = 2e3+5; int n, m; struct Edge { int to, w, next; }edge[MAXM]; int tot, head[MAXN]; void addedge(int u, int v, int w) { edge[tot].to = v; edge[tot].w = w; edge[tot].next = head[u]; head[u] = tot++; edge[tot].to = u; edge[tot].w = w; edge[tot].next = head[v]; head[v] = tot++; } int dis[MAXN], vis[MAXN]; int minb[MAXN]; int spfa(int s) { memset(dis, 0x3f, sizeof(dis)); memset(vis, 0, sizeof(vis)); memset(minb, 0x3f, sizeof(minb)); queue<int> q; dis[s] = 0; minb[s] = 0; vis[s] = 1; q.push(s); while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = 0; for(int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to, w = edge[i].w; if(dis[v] == dis[u] + w) { minb[v] = min(minb[v], minb[u] + 1); if(!vis[v]) { vis[v] = 1; q.push(v); } } if(dis[v] > dis[u] + w) { dis[v] = dis[u] + w; minb[v] = minb[u] + 1; if(!vis[v]) { vis[v] = 1; q.push(v); } } } } } struct Eg { int u, cap, rev; Eg(int uu, int cc, int rr) { u = uu; cap = cc; rev = rr; } }; vector<Eg> G[MAXN]; bool used[MAXN]; void add(int u, int v, int cap) { G[u].push_back(Eg(v, cap, G[v].size())); G[v].push_back(Eg(u, 0, G[u].size()-1)); } void build() { for(int i = 1; i <= n; ++i) { for(int j = head[i]; ~j; j = edge[j].next) { int v = edge[j].to, w = edge[j].w; if(dis[v] - dis[i] == w) { add(i, v, 1); } } } } int dfs(int v, int t, int f) { if(v == t) return f; used[v] = true; for(int i = 0; i < G[v].size(); ++i) { Eg &e = G[v][i]; if(!used[e.u] && e.cap > 0) { int d = dfs(e.u, t, min(f, e.cap)); if(d > 0) { e.cap -= d; G[e.u][e.rev].cap += d; return d; } } } return 0; } int max_flow(int s, int t) { int flow = 0; while(1) { memset(used, 0, sizeof(used)); int f = dfs(s, t, INF); if(f == 0) return flow; flow += f; } } void init() { tot = 0; memset(head, -1, sizeof(head)); for(int i = 0; i <= n; ++i) { G[i].clear(); } } int main() { //freopen("in", "r", stdin); while(~scanf("%d %d", &n, &m)) { init(); for(int i = 0; i < m; ++i) { int u, v, w; scanf("%d %d %d", &u, &v, &w); addedge(u, v, w); } spfa(1); build(); int ans = max_flow(1, n); printf("%d %d\n", ans, m-minb ); } return 0; }
相关文章推荐
- 2015多校联合训练第一场Tricks Device(hdu5294)
- HDU 5294 Tricks Device(2015多校第一场 最短路 + 最小割)
- hdu 5294 Tricks Device(2015多校第一场第7题)最大流+最短路
- hdu 5294 Tricks Device(2015多校第一场第7题)最大流+最短路
- hdu 5294 Tricks Device(2015多校第一场第7题)最大流+最短路
- 2015多校联合训练第一场Assignment(hdu5289)三种解法
- hdu5294||2015多校联合第一场1007 最短路+最大流
- hdu5294||2015多校联合第一场1007 最短路+最大流
- hdu5294 Tricks Device 多校联合赛
- HDU 5294 Tricks Device (最短路上的最小割) 2015多校训练1007
- hdu5289 2015多校联合第一场1002 Assignment
- 2015年多校联合训练第一场OO’s Sequence(hdu5288)
- HDU 4869 Turn the pokers (2014多校联合训练第一场1009) 解题报告(维护区间 + 组合数)
- HDU 5294 Tricks Device (最短路变体) 2015多校联合第一场
- HDU 5294 Tricks Device(多校2015 最大流+最短路啊)
- hdu 4607 park visit 2013多校联合训练第一场
- 2015 ACM多校训练第一场
- [RMQ+二分] 2015多校联合第一场 Assignment
- 2015暑期多校训练第一场 1,2,3
- hdu 4602 partition 2013多校联合训练第一场