HDOJ 5294 Tricks Device 最短路(记录路径)+最小割
最短路记录路径,同一时候求出最短的路径上最少要有多少条边,
然后用在最短路上的边又一次构图后求最小割.
Tricks Device
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1584 Accepted Submission(s): 388
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
/* ***********************************************
Author :CKboss
Created Time :2015年07月24日 星期五 10时07分09秒
File Name :HDOJ5294.cpp
************************************************ */ #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map> using namespace std; typedef pair<int,int> pII; const int INF=0x3f3f3f3f;
const int maxn=2200; int n,m; /*************EDGE********************/ struct Edge
{
int to,next,cost,cap,flow;
}edge[maxn*60],edge2[maxn*60]; int Adj[maxn],Size;
int Adj2[maxn],Size2; void Add_Edge(int u,int v,int c)
{
edge[Size].to=v;
edge[Size].next=Adj[u];
edge[Size].cost=c;
Adj[u]=Size++;
} /********spfa************/ int dist[maxn];
bool inQ[maxn]; vector<int> Pre[maxn]; int spfa(Edge* edge,int* Adj)
{
memset(dist,63,sizeof(dist));
memset(inQ,false,sizeof(inQ));
dist[1]=0;
queue<int> q;
inQ[1]=true;q.push(1); while(!q.empty())
{
int u=q.front();q.pop(); for(int i=Adj[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(dist[v]>dist[u]+edge[i].cost)
{
Pre[v].clear();
Pre[v].push_back(u); dist[v]=dist[u]+edge[i].cost; if(!inQ[v])
{
inQ[v]=true;
q.push(v);
}
}
else if(dist[v]==dist[u]+edge[i].cost)
{
Pre[v].push_back(u);
}
} inQ[u]=false; }
return dist[n];
} /********************rebuild************************/ void Add_Edge2(int u,int v,int w,int rw=0)
{
edge2[Size2].cost=1;
edge2[Size2].to=v; edge2[Size2].cap=w; edge2[Size2].next=Adj2[u];
edge2[Size2].flow=0; Adj2[u]=Size2++; edge2[Size2].cost=1;
edge2[Size2].to=u; edge2[Size2].cap=w; edge2[Size2].next=Adj2[v];
edge2[Size2].flow=0; Adj2[v]=Size2++;
} bool used[maxn];
int edges; void rebuild()
{
memset(used,false,sizeof(used));
queue<int> q;
q.push(n); used[n]=true;
edges=0; while(!q.empty())
{
int v=q.front(); q.pop();
for(int i=0,sz=Pre[v].size();i<sz;i++)
{
int u=Pre[v][i];
/// u--->v
//cout<<u<<" ---> "<<v<<endl;
edges++;
Add_Edge2(u,v,1); if(used[u]==false)
{
used[u]=true; q.push(u);
}
}
}
} /************************max_flow*******************************/ int gap[maxn],dep[maxn],pre[maxn],cur[maxn]; int sap(int start,int end,int N,Edge* edge=edge2)
{
memset(gap,0,sizeof(gap));
memset(dep,0,sizeof(dep));
memcpy(cur,Adj2,sizeof(Adj2)); int u=start;
pre[u]=-1; gap[0]=N;
int ans=0; while(dep[start]<N)
{
if(u==end)
{
int Min=INF;
for(int i=pre[u];~i;i=pre[edge[i^1].to])
{
if(Min>edge[i].cap-edge[i].flow)
Min=edge[i].cap-edge[i].flow;
}
for(int i=pre[u];~i;i=pre[edge[i^1].to])
{
edge[i].flow+=Min;
edge[i^1].flow-=Min;
}
u=start;
ans+=Min;
continue;
} bool flag=false;
int v;
for(int i=cur[u];~i;i=edge[i].next)
{
v=edge[i].to;
if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u])
{
flag=true;
cur[u]=pre[v]=i;
break;
}
} if(flag)
{
u=v; continue;
} int Min=N;
for(int i=Adj2[u];~i;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[pre[u]^1].to;
} return ans;
} void init()
{
memset(Adj,-1,sizeof(Adj)); Size=0;
memset(Adj2,-1,sizeof(Adj2)); Size2=0;
for(int i=1;i<=n;i++) Pre[i].clear();
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout); while(scanf("%d%d",&n,&m)!=EOF)
{
init();
for(int i=0,u,v,c;i<m;i++)
{
scanf("%d%d%d",&u,&v,&c);
Add_Edge(u,v,c); Add_Edge(v,u,c);
}
spfa(edge,Adj);
rebuild();
int max_flow=sap(1,n,n);
int min_short_path=spfa(edge2,Adj2);
printf("%d %d\n",max_flow,m-min_short_path);
} return 0;
}
HDOJ 5294 Tricks Device 最短路(记录路径)+最小割的更多相关文章
- hdu 5294 Tricks Device 最短路建图+最小割
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 Tricks Device Time Limit: 2000/1000 MS (Java/Other ...
- SPFA+Dinic HDOJ 5294 Tricks Device
题目传送门 /* 题意:一无向图,问至少要割掉几条边破坏最短路,问最多能割掉几条边还能保持最短路 SPFA+Dinic:SPFA求最短路时,用cnt[i]记录到i最少要几条边,第二个答案是m - cn ...
- HDU 5294 Tricks Device 最短路+最大流
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5294 题意: 给你个无向图: 1.求最少删除几条边就能破坏节点1到节点n的最短路径, 2.最多能删除 ...
- HDU 5294 Tricks Device (最大流+最短路)
题目链接:HDU 5294 Tricks Device 题意:n个点,m条边.而且一个人从1走到n仅仅会走1到n的最短路径.问至少破坏几条边使原图的最短路不存在.最多破坏几条边使原图的最短路劲仍存在 ...
- 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 网络流 最短路
Tricks Device 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5294 Description Innocent Wu follows D ...
- hdu 5294 Tricks Device(2015多校第一场第7题)最大流+最短路
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 题意:给你n个墓室,m条路径,一个人在1号墓室(起点),另一个人在n号墓室(终点),起点的那 ...
- HDU 5294 Tricks Device (最短路,最大流)
题意:给一个无向图(连通的),张在第n个点,吴在第1个点,‘吴’只能通过最短路才能到达‘张’,两个问题:(1)张最少毁掉多少条边后,吴不可到达张(2)吴在张毁掉最多多少条边后仍能到达张. 思路:注意是 ...
- hdu 4871 树的分治+最短路记录路径
/* 题意:给你一些节点和一些边,求最短路径树上是k个节点的最长的路径数. 解:1.求出最短路径树--spfa加记录 2.树上进行操作--树的分治,分别处理子树进行补集等运算 */ #include& ...
随机推荐
- POJ 1777
一道好题. 由算术基本定理,知: 那么,对于上式的每个因子值只能是2^M的形式.取第一个式子为例,通过分解因式出(1+p^2)=2^k知,a只能为1. 于是对于p只能是梅森素数.而且每个梅森素数只能出 ...
- C++表达式求值(利用数据结构栈)
唉,刚刚用C++又又一次写了一个较完好的表达式求值程序,最后精简后程序还不到100行.这不经让我 想到了大一上学期刚学c语言时自己费了好大的劲,写了几百行并且功能还不是非常齐全(当时还不能计算有括号的 ...
- 开源ext2read代码走读之-在windows下怎样推断有几个硬盘设备?
int get_ndisks() { HANDLE hDevice; // handle to the drive to be examined int n ...
- angularjs1-2,作用域、代码压缩
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- 英语发音规则---S字母
英语发音规则---S字母 一.总结 一句话总结: 1.S 在音节开头或清辅音前 /s/? sit /sɪt/ vt.& vi.坐 seat /si:t/ n.席位 sell /sel/ vt. ...
- Oracle在Linux下的性能优化
Oracle数据库内存参数的优化 Ø 与oracle相关的系统内核参数 Ø SGA.PGA参数设置 Oracle下磁盘存储性能优化 Ø 文件系统的选择(ext2 ...
- vmvare如何安装xp虚拟机
http://jingyan.baidu.com/article/a681b0ded8e25e3b19434640.html 一直以来,许多的朋友都不熟悉怎么安装在虚拟机上装windows系统 200 ...
- POJ 1995 Raising Modulo Numbers 【快速幂取模】
题目链接:http://poj.org/problem?id=1995 解题思路:用整数快速幂算法算出每一个 Ai^Bi,然后依次相加取模即可. #include<stdio.h> lon ...
- XP访问WIN10共享打印机提示错误:操作无法完成,拒绝访问
XP系统添加打印机--连接到此计算机的本地打印机(取消自动检测)--创建新端口(LOCAL port)----输入端口名\\计算机名\打印机名.(例如:\\adubei\\HP lasjet 1020 ...
- Unity 声音播放不受Time.scale为0的影响
其他会暂停,目前发现声音不受影响 嗯,就这样.