Key Vertex

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1347    Accepted Submission(s): 305

Problem Description
You need walking from vertex S to vertex T in a graph. If you remove one vertex which stops you from walking from S to T, that vertex we call as key vertex. Now you are given a directed graph, S and T, and you should tell us how many
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.
 

Input
The input consists of multiply test cases. The first line of each test case contains two integers, n(0 <= n <= 100000), m(0 <= m <= 300000), which are the number of vertexes and the number of edge. Each of the next m lines consists
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).

 

Output
Output the number of key vertexes in a single line for each test case.
 

Sample Input

6 6
0 1
1 2
1 3
2 4
3 4
4 5
0 5
 

Sample Output

4
 

Author
momodi
 

Source
 

Recommend
wxl   |   We have carefully selected several similar problems for you:  

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 求起点到终点路径上的割点)的更多相关文章

  1. hdu 1240 3维迷宫 求起点到终点的步数 (BFS)

    题意,给出一个N,这是这个三空间的大小,然后给出所有面的状况O为空地,X为墙,再给出起始点的三维坐标和终点的坐标,输出到达的步数 比较坑 z是x,x是y,y是z,Sample InputSTART 1 ...

  2. HDU 3313 Key Vertex(dfs + bfs)

    HDU 3313 Key Vertex 题目链接 题意:一个有向无环图.求s,t之间的割点 思路:先spfa找一条最短路出来,假设不存在.就n个都是割点. 然后每次从s进行dfs,找到能经过最短路上的 ...

  3. HDU 4607 Park Visit 两次DFS求树直径

    两次DFS求树直径方法见 这里. 这里的直径是指最长链包含的节点个数,而上一题是指最长链的路径权值之和,注意区分. K <= R: ans = K − 1; K > R:   ans = ...

  4. hdu1428之spfa+dfs

    漫步校园 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  5. 【PAT甲级】1003 Emergency (25 分)(SPFA,DFS)

    题意:n个点,m条双向边,每条边给出通过用时,每个点给出点上的人数,给出起点终点,求不同的最短路的数量以及最短路上最多能通过多少人.(N<=500) AAAAAccepted code: #in ...

  6. 【PAT甲级】1030 Travel Plan (30 分)(SPFA,DFS)

    题意: 输入N,M,S,D(N,M<=500,0<S,D<N),接下来M行输入一条边的起点,终点,通过时间和通过花费.求花费最小的最短路,输入这条路径包含起点终点,通过时间和通过花费 ...

  7. DFS入门之二---DFS求连通块

    用DFS求连通块也是比较典型的问题, 求多维数组连通块的过程也称为--“种子填充”. 我们给每次遍历过的连通块加上编号, 这样就可以避免一个格子访问多次.比较典型的问题是”八连块问题“.即任意两格子所 ...

  8. hdu 1983(BFS+DFS) 怪盗Kid

    http://acm.hdu.edu.cn/showproblem.php?pid=1983 首先,题目要求出口和入口不能封闭,那么,只要把出口或入口的周围全给封闭了那盗贼肯定无法成功偷盗,出口或入口 ...

  9. 【10.31校内测试】【组合数学】【记忆化搜索/DP】【多起点多终点二进制拆位Spfa】

    Solution 注意取模!!! Code #include<bits/stdc++.h> #define mod 1000000007 #define LL long long usin ...

随机推荐

  1. eclipse闪退解决(转)

    最近帮同事解决一个eclipse闪退解决的问题,从网上找了N多方法皆无效,最后用一个园友的博客上的方法解决了,特转载一下. 解决办法: 删除文件 [workspace]/.metadata/.plug ...

  2. CAT架构的应用与实践 IT大咖说 - 大咖干货,不再错过

    CAT架构的应用与实践 IT大咖说 - 大咖干货,不再错过 http://www.itdks.com/dakashuo/new/dakalive/detail/594

  3. Cortex-M4 Core Registers

    Cortex-M4 Core Registers Goal: visualizing what happens to the Cortex-M4 core registers after reset ...

  4. SQL Server、Oracle和MySQL中查出值为NULL的替换

    参考文献: http://database.51cto.com/art/200803/67397.htm 正文 在SQL Server Oracle MySQL当数据库中查出某值为NULL怎么办? 1 ...

  5. C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\文件不断增长,如何处理?

    很久没有写博了.最近半年除了忙活布置新家和过年期间走亲访友之外,都是在公司处理一些项目中的杂事:连家里买的很多书都停下来没看了,感觉这段时间在事业和学习上一直都是忙忙碌碌,却又碌碌无为. 吐槽完,说正 ...

  6. 源码编译Tkinter

    要让Python支持Tkinter, 需要首先安装tcl和tk两个软件包. 下载地址: http://www.tcl.tk/software/tcltk/download.html 或 tcl:htt ...

  7. Android 模拟器设置

    这几个图标你应该是没有见过的,我来简单为你介绍下.最左边的图标其实你已经比较熟悉了,就是你睡觉前使用过的Android SDK管理器,点击它和点击SDK Manager效果是一样的.中间的图标是用来开 ...

  8. C#编程(七十四)----------释放非托管资源

    释放非托管资源 在介绍释放非托管资源的时候,我觉得有必要先来认识一下啥叫非托管资源,既然有非托管资源,肯定有托管资源. 托管资源指的是.net可以自棕进行回收的资源,主要是指托管堆上分配的内存资源.托 ...

  9. C#编程(十八)----------C#中的结构

    C#中的结构 假设有一个类: class Dimensions { public double Length; public double Width; } 定义了一个类,它只存储某一项的长度和宽度. ...

  10. 【Devops】【docker】【CI/CD】关于jenkins构建成功后一步,执行的shell命令详解+jenkins容器运行宿主机shell命令的实现方法

    1.展示这段shell命令 +详解 #================================================================================= ...