HDU5294 Tricks Device(最大流+SPFA) 2015 Multi-University Training Contest 1
Tricks Device
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 389 Accepted Submission(s): 100
chambers. Innocent Wu wants to catch up Dumb Zhang to find out the answers of some questions, however, it’s Dumb Zhang’s intention to keep Innocent Wu in the dark, to do which he has to stop Innocent Wu from getting him. Only via the original shortest ways
from the entrance to the end of the tomb costs the minimum time, and that’s the only chance Innocent Wu can catch Dumb Zhang.
Unfortunately, Dumb Zhang masters the art of becoming invisible(奇门遁甲) and tricks devices of this tomb, he can cut off the connections between chambers by using them. Dumb Zhang wanders how many channels at least he has to cut to stop Innocent Wu. And Innocent
Wu wants to know after how many channels at most Dumb Zhang cut off Innocent Wu still has the chance to catch Dumb Zhang.
For each case,the first line must includes two integers, N(<=2000), M(<=60000). N is the total number of the chambers, M is the total number of the channels.
In the following M lines, every line must includes three numbers, and use ai、bi、li as channel i connecting chamber ai and bi(1<=ai,bi<=n), it costs li(0<li<=100) minute to pass channel i.
The entrance of the tomb is at the chamber one, the end of tomb is at the chamber N.
8 9
1 2 2
2 3 2
2 4 1
3 5 3
4 5 4
5 8 1
1 6 2
6 7 5
7 8 1
2 6
pid=5299" target="_blank">5299
5298pid=5297" target="_blank">5297
5296pid=5295" target="_blank">5295
#include<stdio.h>
#include<string.h>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
#define captype int const int MAXN = 2010; //点的总数
const int MAXM = 400010; //边的总数
const int INF = 1<<30;
struct EDG{
int to,next;
captype cap,flow;
int d;
} edg[MAXM];
int eid,head[MAXN];
int gap[MAXN]; //每种距离(或可觉得是高度)点的个数
int dis[MAXN]; //每一个点到终点eNode 的最短距离
int cur[MAXN]; //cur[u] 表示从u点出发可流经 cur[u] 号边
int pre[MAXN];
int D[MAXN], vist[MAXN], mindis; void init(){
eid=0;
memset(head,-1,sizeof(head));
}
//有向边 三个參数。无向边4个參数
void addEdg(int u,int v,int d,captype rc=0){
edg[eid].to=v; edg[eid].next=head[u]; edg[eid].d=d;
edg[eid].cap=1; edg[eid].flow=0; head[u]=eid++; edg[eid].to=u; edg[eid].next=head[v]; edg[eid].d=INF;
edg[eid].cap=rc; edg[eid].flow=0; head[v]=eid++;
}
captype maxFlow_sap(int sNode,int eNode, int n){//n是包含源点和汇点的总点个数,这个一定要注意
memset(gap,0,sizeof(gap));
memset(dis,0,sizeof(dis));
memcpy(cur,head,sizeof(head));
memset(vist,-1,sizeof(vist));
pre[sNode] = -1;
gap[0]=n;
captype ans=0; //最大流
vist[sNode]=0;
int u=sNode ,i ;
while(dis[sNode]<n){ //推断从sNode点有没有流向下一个相邻的点
if(u==eNode){ //找到一条可增流的路
captype Min=INF ;
int inser;
for( i=pre[u]; i!=-1; i=pre[edg[i^1].to]) //从这条可增流的路找到最多可增的流量Min
if(Min>edg[i].cap-edg[i].flow){
Min=edg[i].cap-edg[i].flow;
inser=i;
}
for( i=pre[u]; i!=-1; i=pre[edg[i^1].to]){
edg[i].flow+=Min;
edg[i^1].flow-=Min; //可回流的边的流量
}
ans+=Min;
u=edg[inser^1].to;
continue;
}
bool flag = false; //推断是否能从u点出发可往相邻点流
int v;
for( i=cur[u]; i!=-1; i=edg[i].next){
v=edg[i].to;
if(edg[i].cap>0&&vist[u]+edg[i].d+D[v]!=mindis)//假设是正流,则必须保证是最短的一条路,假设是逆流。表明v点己是在最短路上
continue;
vist[v]=mindis-D[v];
if( edg[i].cap-edg[i].flow>0 && dis[u]==dis[v]+1){
flag=true;
cur[u]=pre[v]=i;
break;
}
}
if(flag){
u=v;
continue;
}
//假设上面没有找到一个可流的相邻点。则改变出发点u的距离(也可觉得是高度)为相邻可流点的最小距离+1
int Mind= n;
for( i=head[u]; i!=-1; i=edg[i].next){
v=edg[i].to;
if(edg[i].cap>0&&vist[u]+edg[i].d+D[v]!=mindis)
continue;
vist[v]=mindis-D[v];
if( edg[i].cap-edg[i].flow>0 && Mind>dis[v]){
Mind=dis[v];
cur[u]=i;
}
} gap[dis[u]]--;
if(gap[dis[u]]==0) return ans; //当dis[u]这样的距离的点没有了,也就不可能从源点出发找到一条增广流路径
//由于汇点到当前点的距离仅仅有一种,那么从源点到汇点必定经过当前点,然而当前点又没能找到可流向的点,那么必定断流
dis[u]=Mind+1;//假设找到一个可流的相邻点,则距离为相邻点距离+1。假设找不到,则为n+1
gap[dis[u]]++;
if(u!=sNode) u=edg[pre[u]^1].to; //退一条边
}
return ans;
}
int numk[MAXN];
void spfa(int s,int t,int n){
queue<int>q;
int inq[MAXN]={0},i;
for( i=1; i<=n; i++)
D[i]=INF;
D[t]=0; numk[t]=0;
q.push(t);
while(!q.empty()){
int u=q.front(); q.pop();
inq[u]=0;
for( i=head[u]; i!=-1; i=edg[i].next)
if(edg[i].d==INF&&D[edg[i].to]>D[u]+edg[i^1].d){
D[edg[i].to]=D[u]+edg[i^1].d;
numk[edg[i].to]=numk[u]+1;
if(inq[edg[i].to]==0)
inq[edg[i].to]=1,q.push(edg[i].to);
}
else if(edg[i].d==INF&&D[edg[i].to]==D[u]+edg[i^1].d&&numk[edg[i].to]>numk[u]+1)
{
numk[edg[i].to]=numk[u]+1;
if(inq[edg[i].to]==0)
inq[edg[i].to]=1,q.push(edg[i].to);
}
}
} int main()
{
int n,m,u,v,cost;
while(scanf("%d%d",&n,&m)>0)
{
init();
for(int i=1; i<=m; i++)
{
scanf("%d%d%d",&u,&v,&cost);
addEdg(u,v,cost);
addEdg(v,u,cost);
}
spfa(1,n,n);
int ans1,ans2;
ans2=m-numk[1];
mindis=D[1];
ans1=maxFlow_sap(1,n,n);
printf("%d %d\n",ans1,ans2);
}
}
HDU5294 Tricks Device(最大流+SPFA) 2015 Multi-University Training Contest 1的更多相关文章
- HDU 5294 Tricks Device(多校2015 最大流+最短路啊)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 Problem Description Innocent Wu follows Dumb Zha ...
- HDU 5294 Tricks Device (最大流+最短路)
题目链接:HDU 5294 Tricks Device 题意:n个点,m条边.而且一个人从1走到n仅仅会走1到n的最短路径.问至少破坏几条边使原图的最短路不存在.最多破坏几条边使原图的最短路劲仍存在 ...
- HDU5294——Tricks Device(最短路 + 最大流)
第一次做最大流的题目- 这题就是堆模板 #include <iostream> #include <algorithm> #include <cmath> #inc ...
- hdu 3572 Task Schedule(最大流)2010 ACM-ICPC Multi-University Training Contest(13)——Host by UESTC
题意: 告诉我们有m个任务和k个机器.第i个任务需要ci天完成,最早从第ai天开始,最晚在第bi天结束.每台机器每天可以执行一个任务.问,是否可以将所有的任务都按时完成? 输入: 首行输入一个整数t, ...
- Tricks Device (hdu 5294 最短路+最大流)
Tricks Device Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) To ...
- SPFA+Dinic HDOJ 5294 Tricks Device
题目传送门 /* 题意:一无向图,问至少要割掉几条边破坏最短路,问最多能割掉几条边还能保持最短路 SPFA+Dinic:SPFA求最短路时,用cnt[i]记录到i最少要几条边,第二个答案是m - cn ...
- 2015 Multi-University Training Contest 1 Tricks Device
Tricks Device Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tot ...
- HDOJ 5294 Tricks Device 最短路(记录路径)+最小割
最短路记录路径,同一时候求出最短的路径上最少要有多少条边, 然后用在最短路上的边又一次构图后求最小割. Tricks Device Time Limit: 2000/1000 MS (Java/Oth ...
- hdu 5294 Tricks Device 最短路建图+最小割
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 Tricks Device Time Limit: 2000/1000 MS (Java/Other ...
随机推荐
- pycharm debug后会出现 step over /step into/step into my code /force step into /step out 分别表示
1.debug,全部打印 2.打断点debug,出现单步调试等按钮,只运行断点前 3.setup over 调试一行代码 4.setup out 运行断点后面所有代码 5.debug窗口显示调试按钮 ...
- (C/C++学习)17.bitset(位操作)
说明:bitset 就像 vector 一样,是 C++ 的一个类模板库,用来对一个数的二进制位进行管理.判断等操作,使用时需要包含头文件 #include<bitset>. 1.声明及定 ...
- CentOS虚拟机挂载Windows共享目录
Windows文件共享使用了SMB协议(又称CIFS协议),该协议主要提供了文件共享和打印共享功能,分别使用TCP 139和445端口.UNIX.Linux系统提供了该协议的开源实现samba.为了方 ...
- 实现基于pam认证的vsftpd
1 需求 使用指定虚拟用户Allen与Barry登录ftp,认证的源是mysql服务器: Allen可以上传文件,Barry不可以上传文件: 2 环境 [root@centos7 ~]# cat /e ...
- MongoDB的游标操作
MongoDB的游标操作 制作人:全心全意 游标:查询的返回资源或接口,这个接口可以逐条查询 游标的声明 var cursor = db.collection名.find(); cursor.hasN ...
- UVA 10652 凸包问题
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> # ...
- [luoguP1033] 自由落体(模拟?)
传送门 这不能算是数论题... 卡精度这事noip也做的出来.. 代码 #include <cmath> #include <cstdio> int n, ans; doubl ...
- bzoj 2223 [Coci 2009]PATULJCI
[Coci 2009]PATULJCI Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 1286 Solved: 553[Submit][Status ...
- POJ 2104 K-th Number (可持久化线段树)
题目大意 给一个长度为n的序列,有m个询问,每次询问一个区间里面第k小的数. 解题分析 静态的区间第k大.复习了一下可持久化线段树. 首先对数值离散化,建一颗权值线段树.按照序列的顺序依次插入,每一个 ...
- Linux下汇编语言学习笔记6 ---
这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...