标签:
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