标签:
6 6 0 1 1 2 1 3 2 4 3 4 4 5 0 5
4
题意:给出一个有向无环图,问从S点到T点有多少个关键点(即每条路都必过的点),如果没有路从S到T,那么所有的点都是关键点。
解题:因为要求关键点,那么我们可以求一条从S到T的最短路,那么所有的关键点必然在这一条最短路上,我们把这条最短路上所有的点按经过的倒至顺序从0都标一个号,其他的点都标为-1,每一次第一个加入队列里面的都是必须点。再找的过程中更新必须点的指向。
#include<stdio.h> #include<string.h> #include<queue> using namespace std; #define MAXN 100005 #define MAXM 300005 struct EDG{ int to,next; }edg[MAXM]; int eid,head[MAXN]; void init() { eid=0; memset(head,-1,sizeof(head)); } void addedg(int u,int v) { edg[eid].to=v; edg[eid].next=head[u]; head[u]=eid++; } int vist[MAXN],flagMark[MAXN]; bool bfs1(int s,int t) { memset(vist,-1,sizeof(vist)); vist[s]=-2; queue<int>q; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u]; i!=-1; i=edg[i].next) { int v=edg[i].to; if(vist[v]==-1) vist[v]=u,q.push(v); if(v==t) { memset(flagMark,-1,sizeof(flagMark)); int mark=0; while(v!=-2) { flagMark[v]=mark; mark++; v=vist[v]; } return 1; } } } return 0; } int bfs2(int s,int t,int n) { bool flag=bfs1(s,t); if(flag==0) return n; queue<int>q; memset(vist,0,sizeof(vist)); int mark=flagMark[s]; int mustnode=s; int ans=2; vist[s]=1; q.push(s); while(!q.empty()) { while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u]; i!=-1; i=edg[i].next) { int v=edg[i].to; if(flagMark[v]==-1) { if(vist[v]==0) vist[v]=1,q.push(v); } else if(flagMark[v]<mark) //更新必须点的指向 { mark=flagMark[v]; mustnode=v; if(mustnode==t) return ans; } } } ans++; q.push(mustnode); } return ans; } int main() { int n,m,u,v; int s,t; while(scanf("%d%d",&n,&m)>0) { init(); while(m--) { scanf("%d%d",&u,&v); addedg(u,v); } scanf("%d%d",&s,&t); printf("%d\n",bfs2(s,t,n)); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU 3313 Key Vertex(BFS+BFS) 求S点到T点路径的关键点
标签:
原文地址:http://blog.csdn.net/u010372095/article/details/47146385