HDU 5294 Tricks Device (最大流+最短路)
题目链接:HDU 5294 Tricks Device
题意:n个点,m条边,并且一个人从1走到n只会走1到n的最短路径,问至少破坏几条边使原图的最短路不存在,最多破坏几条边使原图的最短路劲仍存在
思路:
1.跑一遍最短路,记录下所有最短路径,将这些最短路径的边以(0,1)(流量,容量)加到网络流中,跑一遍最大流
2.记录下的所有最短路径,再加到新的最短路的图中,边权为1,跑一遍最短路,m-最短路 就是答案
注意:有重边的情况
比如:
2 3
1 2 1
1 2 1
1 2 1
ans: 3 2
AC代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <set>
using namespace std;
const int MAXN=2010;
const int MAXM=60010;
#define typec int
const typec INF=0x3f3f3f3f;//防止后面溢出,这个不能太大struct Edge {int to,next,cap,flow;
} edge[MAXM*4]; //注意是MAXM
int tol;
int head[MAXN];
int gap[MAXN],dep[MAXN],cur[MAXN];
void add(int u,int v,int w,int rw = 0) {edge[tol].to = v;edge[tol].cap = w;edge[tol].flow = 0;edge[tol].next = head[u];head[u] = tol++;edge[tol].to = u;edge[tol].cap = rw;edge[tol].flow = 0;edge[tol].next = head[v];head[v] = tol++;
}
int Q[MAXN];
void BFS(int start,int end) {memset(dep,-1,sizeof(dep));memset(gap,0,sizeof(gap));gap[0] = 1;int front = 0, rear = 0;dep[end] = 0;Q[rear++] = end;while(front != rear) {int u = Q[front++];for(int i = head[u]; i != -1; i = edge[i].next) {int v = edge[i].to;if(dep[v] != -1)continue;Q[rear++] = v;dep[v] = dep[u] + 1;gap[dep[v]]++;}}
}
int S[MAXN];
int sap(int start,int end,int N) {BFS(start,end);memcpy(cur,head,sizeof(head));int top = 0;int u = start;int ans = 0;while(dep[start] < N) {if(u == end) {int Min = INF;int inser;for(int i = 0; i < top; i++)if(Min > edge[S[i]].cap - edge[S[i]].flow) {Min = edge[S[i]].cap - edge[S[i]].flow;inser = i;}for(int i = 0; i < top; i++) {edge[S[i]].flow += Min;edge[S[i]^1].flow -= Min;}ans += Min;top = inser;u = edge[S[top]^1].to;continue;}bool flag = false;int v;for(int i = cur[u]; i != -1; i = edge[i].next) {v = edge[i].to;if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u]) {flag = true;cur[u] = i;break;}}if(flag) {S[top++] = cur[u];u = v;continue;}int Min = N;for(int i = head[u]; i != -1; i = edge[i].next)if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min) {Min = dep[edge[i].to];cur[u] = i;}gap[dep[u]]--;if(!gap[dep[u]])return ans;dep[u] = Min + 1;gap[dep[u]]++;if(u != start)u = edge[S[--top]^1].to;}return ans;
}
void init() {tol = 0;memset(head,-1,sizeof(head));
}//-------------------------------------------------
struct Edge2 {int v;int cost;Edge2(int _v=0,int _cost=0):v(_v),cost(_cost){}
};
vector<Edge2>E[MAXN],E2[MAXN];
void addedge(int u,int v,int w) {E[u].push_back(Edge2(v,w));
}
bool vis[MAXN];//在队列标志
int cnt[MAXN];//每个点的入队列次数
int dist[MAXN];bool SPFA(int start,int n) {memset(vis,false,sizeof(vis));for(int i=1;i<=n;i++) dist[i]=INF;vis[start]=true;dist[start]=0;queue<int>que;while(!que.empty())que.pop();que.push(start);memset(cnt,0,sizeof(cnt));cnt[start]=1;while(!que.empty()) {int u=que.front();que.pop();vis[u]=false;for(int i=0;i<E[u].size();i++){int v=E[u][i].v;if(dist[v]>dist[u]+E[u][i].cost){dist[v]=dist[u]+E[u][i].cost;if(!vis[v]){vis[v]=true;que.push(v);if(++cnt[v]>n) return false;//cnt[i]为入队列次数,用来判定是否存在负环回路}}}}return true;
}set<int> s;
int main() {int i,j,m,n;int a,b,c;while(scanf("%d %d",&n,&m)!=EOF) {init();s.clear();for(i=1;i<=n;i++) E[i].clear();for(i=0; i<m; i++) {scanf("%d %d %d",&a,&b,&c);addedge(a,b,c);addedge(b,a,c);}int ok=SPFA(1,n);for(i=1;i<=n;i++){E2[i]=E[i];E[i].clear();}for(i=1; i<=n; i++) {int sz=E2[i].size();for(j=0; j<sz; j++) {int u=i;int v=E2[i][j].v;//得到最短路的边if(dist[u]+E2[i][j].cost==dist[v]) {add(u,v,1);s.insert(u),s.insert(v);addedge(u,v,1);}}}int ans=sap(1,n,(int)s.size());ok=SPFA(1,n);printf("%d %d\n",ans,m-dist[n]);}return 0;
}
/*
2 3
1 2 1
1 2 1
1 2 1
2 5
1 2 2
1 2 2
1 2 1
1 2 1
1 2 1
*/
HDU 5294 Tricks Device (最大流+最短路)相关推荐
- HDU 5294 Tricks Device(最短路+最大流)
题意:给一个无向图(连通的),张在第n个点,吴在第1个点,'吴'只能通过最短路才能到达'张',两个问题:(1)张最少毁掉多少条边后,吴不可到达张(2)吴在张毁掉最多多少条边后仍能到达张. 思路:将所有 ...
- hdu 5294 Tricks Device
中规中矩的做法,第二发SAP.贴一发留恋. #include<cstdio> #include<cstring> #include<algorithm> #incl ...
- Tricks Device 最短路+最大流
http://acm.hdu.edu.cn/webcontest/contest_showproblem.php?pid=1006&ojid=0&cid=12578&hide= ...
- HDU - 3416 Marriage Match IV(最大流+最短路)
题目链接:点击查看 题目大意:给出一个由n个点和m条边组成的无环有向图,有自环,有重边,现在给出起点st和终点ed,问从st到ed共有多少条最短路,每条路最多只能经过一次 题目分析:看完题意后感觉是要 ...
- POJ 2135 Farm Tour amp;amp; HDU 2686 Matrix amp;amp; HDU 3376 Matrix Again 费用流求来回最短路...
累了就要写题解,近期总是被虐到没脾气. 来回最短路问题貌似也能够用DP来搞.只是拿费用流还是非常方便的. 能够转化成求满流为2 的最小花费.一般做法为拆点,对于 i 拆为2*i 和 2*i+1.然后连 ...
- 【HDU】4411 Arrest 费用流
传送门:[HDU]4411 Arrest 题目分析:题目的意思一开始没看懂= =...题意大致为:派出至多K个警队遵守先灭小的再灭老的的原则将N个城市的帮派全端了(要灭编号大的必须要先灭编号小的).且 ...
- HDU 4411 Arrest(费用流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4411 题意:有n+1个城市,编号0到n.其中警察局在0号城市,1到n号城市中每个城市都有一个小偷.现在 ...
- 【HDU - 2112】 HDU Today(dijkstra单源最短路 + map转换)
题干: HDU Today Time Limit : 15000/5000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Tota ...
- HDU 5383 Yu-Gi-Oh!(费用流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5383 题意:游戏王同调召唤的方法,每只怪兽有等级和攻击力,两种不同类型的怪兽可以在一定限制下召唤出某一 ...
- hdu 2066 一个人的旅行(最短路)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2066 Problem Description 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里 ...
最新文章
- kmp求前缀和后缀的最大重复部分
- 判断一个窗口是否有焦点_判断一个项目是否值得加盟的基本方法
- Android Service介绍
- D:\我的文档\收藏夹
- 苹果自己设计芯片,但是还是绕不过高通
- 解决:java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal
- Java 获取链表的元素
- 如何设置 jqplot 图表插件的轴和网格
- Linux文件系统变成只读的解决方法
- java集成agent作用_javaagent 基于 javaagent 开发的 APM 工具,收集方法的执行次数和执行时间,定时输出成 json 格式 @codeKK Android开源站...
- PowerShell: 如何使用powershell处理Excel
- 【LaTeX】Research Proposal的模板、一些技巧(包含:横线的制作,标题和摘要的排版)
- 最全的英语收藏夹(精品)
- 英语写作——常用的 过度词-连接词
- “征信污点”可消除?征信中心:不可能
- 28岁想入行软件测试,可行吗?
- 在浏览器中输入网址到网页展现全部过程
- OneNav一为主题魔改教程(四):自定义网址内容页的Tag标签到任意位置--洞五洞洞幺
- VUE饿了么学习笔记(6)goods界面滚动和点击联动的实现
- 2021年三月计算机一级ms,2021年计算机一级Ms Office试题(总)