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
HDOJ Monthly Contest – 2010.02.06
Recommend
wxl | We have carefully selected several similar problems for you: 3251 3310 3311 3314 3376
题意:n个点m条边的有向图,问存在多少个点使得去掉这个点及相连的边后起点和终点不再联通。
思路:很容易想到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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。