Key Vertex (hdu 3313 SPFA+DFS 求起点到终点路径上的割点)
Key Vertex
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1347 Accepted Submission(s): 305
key vertexes are there in the graph.
Please notice that S and T are key vertexes and if S cannot walking to T by the directed edge in the initial graph then all vertexes becomes to key vertexes.
of two integers, u, v(0 <= u, v < n; u != v), indicating there exists an edge from vertex u to vertex v. There might be multiple edges but no loops. The last line of each test case contains two integers, S, T(0 <= S, T < n, S != T).
0 1
1 2
1 3
2 4
3 4
4 5
0 5
pid=3251">3251
3310 3311 3314 3376题意:n个点m条边的有向图,问存在多少个点使得去掉这个点及相连的边后起点和终点不再联通。
思路:非常easy想到Tarjan算法求割点,可是略微一想就会知道不正确,由于Tarjan算法求的是整个图的割点,而这里题目仅仅要求能使起点和终点不连通的点。
然后我们先用SPFA求出一条最短路径,那么要求的“割点”一定都在这条路径上,细致想想就会知道。求出最短路径后从起点dfs。直到找到距离start最远的且在最短路径上的点v。那么v就是一个割点,这时更新start。令start=v,反复上面的dfs直到终点。
为什么这么做呢?你能够在纸上画绘图就会非常快明确了。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b) for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b) for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v) memset ((t) , v, sizeof(t))
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf printf
#define DBG pf("Hi\n")
typedef long long ll;
using namespace std; #define INF 0x3f3f3f3f
#define mod 1000000009
const int maxn = 1005;
const int MAXN = 100010;
const int MAXM = 300010;
const int N = 1005; int n,m; struct Edge
{
int u,v,next;
}edge[MAXM]; int head[MAXN],dist[MAXN],pre[MAXN];
bool inq[MAXN],mark[MAXN],vis[MAXN];
int num,start,End; void init()
{
num=0;
mem(head,-1);
} void addedge(int u,int v)
{
edge[num].u=u;
edge[num].v=v;
edge[num].next=head[u];
head[u]=num++;
} bool SPFA(int s,int t)
{
mem(inq,false);
mem(mark,false);
mem(dist,INF);
mem(pre,-1);
dist[s]=0;
inq[s]=true;
queue<int>Q;
Q.push(s);
while(!Q.empty())
{
int u=Q.front();
Q.pop();
inq[u]=false;
for (int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].v;
if (dist[v]>dist[u]+1)
{
dist[v]=dist[u]+1;
pre[v]=u;
if (!inq[v])
{
inq[v]=true;
Q.push(v);
}
}
}
}
if (dist[t]>=INF) return false;
int x=t;
mem(mark,false);
while (x!=-1)
{
mark[x]=true;
x=pre[x];
}
return true;
} void dfs(int u)
{
if (vis[u]) return ;
vis[u]=true;
for (int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].v;
if (mark[v]&&dist[v]>=dist[start]) //由于有重边,所以一定要加等号,坑了我好久=-=
{
start=v;
continue;
}
dfs(v);
}
return ;
} //void dfs(int u) //第二种写法
//{
// for (int i=head[u];~i;i=edge[i].next)
// {
// int v=edge[i].v;
// if (vis[v]) continue;
// vis[v]=true;
// if (mark[v]&&dist[v]>dist[start])
// {
// start=v;
// continue;
// }
// dfs(v);
// }
// return ;
//} int main()
{
#ifndef ONLINE_JUDGE
freopen("C:/Users/lyf/Desktop/IN.txt","r",stdin);
#endif
int i,j,u,v;
while (~sff(n,m))
{
init();
for (i=0;i<m;i++)
{
sff(u,v);
addedge(u,v);
}
sff(start,End);
if (!SPFA(start,End))
{
pf("%d\n",n);
continue;
}
int ans=0;
mem(vis,false);
while (start!=End)
{
// printf("++%d\n",start);
dfs(start);
// printf("--%d\n",start);
ans++;
}
printf("%d\n",ans+1);
}
return 0;
}
Key Vertex (hdu 3313 SPFA+DFS 求起点到终点路径上的割点)的更多相关文章
- hdu 1240 3维迷宫 求起点到终点的步数 (BFS)
题意,给出一个N,这是这个三空间的大小,然后给出所有面的状况O为空地,X为墙,再给出起始点的三维坐标和终点的坐标,输出到达的步数 比较坑 z是x,x是y,y是z,Sample InputSTART 1 ...
- HDU 3313 Key Vertex(dfs + bfs)
HDU 3313 Key Vertex 题目链接 题意:一个有向无环图.求s,t之间的割点 思路:先spfa找一条最短路出来,假设不存在.就n个都是割点. 然后每次从s进行dfs,找到能经过最短路上的 ...
- HDU 4607 Park Visit 两次DFS求树直径
两次DFS求树直径方法见 这里. 这里的直径是指最长链包含的节点个数,而上一题是指最长链的路径权值之和,注意区分. K <= R: ans = K − 1; K > R: ans = ...
- hdu1428之spfa+dfs
漫步校园 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- 【PAT甲级】1003 Emergency (25 分)(SPFA,DFS)
题意:n个点,m条双向边,每条边给出通过用时,每个点给出点上的人数,给出起点终点,求不同的最短路的数量以及最短路上最多能通过多少人.(N<=500) AAAAAccepted code: #in ...
- 【PAT甲级】1030 Travel Plan (30 分)(SPFA,DFS)
题意: 输入N,M,S,D(N,M<=500,0<S,D<N),接下来M行输入一条边的起点,终点,通过时间和通过花费.求花费最小的最短路,输入这条路径包含起点终点,通过时间和通过花费 ...
- DFS入门之二---DFS求连通块
用DFS求连通块也是比较典型的问题, 求多维数组连通块的过程也称为--“种子填充”. 我们给每次遍历过的连通块加上编号, 这样就可以避免一个格子访问多次.比较典型的问题是”八连块问题“.即任意两格子所 ...
- hdu 1983(BFS+DFS) 怪盗Kid
http://acm.hdu.edu.cn/showproblem.php?pid=1983 首先,题目要求出口和入口不能封闭,那么,只要把出口或入口的周围全给封闭了那盗贼肯定无法成功偷盗,出口或入口 ...
- 【10.31校内测试】【组合数学】【记忆化搜索/DP】【多起点多终点二进制拆位Spfa】
Solution 注意取模!!! Code #include<bits/stdc++.h> #define mod 1000000007 #define LL long long usin ...
随机推荐
- Dos常用命令大全
dos命令进入文件夹 输入 D: 回车,进入D盘的根目录,然后输入dir 回车 可以查看根目录下的文件和文件夹, 输入 cd空格文件夹的名字(不区分大小写) 进入文件夹根目录下, 依次输入dir 查 ...
- Linux学习笔记07—mysql的配置
一.mysql简介 说到数据库,我们大多想到的是关系型数据库,比如mysql.oracle.sqlserver等等,这些数据库软件在windows上安装都非常的方便,在Linux上如果要安装数据库,咱 ...
- phpexcel错误 You tried to set a sheet active by the out of bounds index: 1解决办法
$objPHPExcel->createSheet($k);
- Sed&awk笔记之awk篇(转)
Awk是什么 Awk.sed与grep,俗称Linux下的三剑客,它们之间有很多相似点,但是同样也各有各的特色,相似的地方是它们都可以匹配文本,其中sed和awk还可以用于文本编辑,而grep则不具备 ...
- 阿里云esc云服务器IP不能访问的解决办法
问题:阿里云服务器,专有网络,web设置完毕,在服务器中localhost能够访问,并且关闭防火墙,但是使用公网ip无法访问. 解决:找到本实例安全组,配置规则,按照要求填入80或其他端口.配置完成后 ...
- golang-bcc-bpf-function-tracing
http://www.brendangregg.com/blog/2017-01-31/golang-bcc-bpf-function-tracing.html
- RabbitMQ的应用场景以及基本原理介绍(转)
本文转自https://blog.csdn.net/whoamiyang/article/details/54954780 1.背景 RabbitMQ是一个由erlang开发的AMQP(Advanve ...
- android&php 加密解密
from://http://blog.csdn.net/hecker385/article/details/6717647 android&php 加密解密 分类: Php Android20 ...
- 如何在 Xcode 中修改应用的名字
找到 TARGETS 中的 Build Setting ,下拉找到 Packaging ,修改 Product Name 即可.
- linux设置允许和禁止访问的IP host.allow 和 host.deny
对于能过xinetd程序启动的网络服务,比如ftp telnet,我们就可以修改/etc/hosts.allow和/etc/hosts.deny的配制,来许可或者拒绝哪些IP.主机.用户可以访问. 比 ...