P1144 最短路计数

这一题其实真的很简单,bfs而已

简单分析:

先说一下bfs的原理:

**因为是“一层一层”的搜索,
所以但权值一样是搜到的第一个即为最先的!!!!**
,而dfs还需判断。(不过据说bfs在某些题比较慢)

特点:
第一个搜到的即为最短的
**要权值一样!!!**

简单应用:(及模板)

void bfs(int x,int y){
	queue<int>q; //定义一个队列,由于该STL可以“动态”开数组(即使比较慢)
	q.push(x);
	初始化;
	while(!q.empty()){  //队列不为空
		int u=q.front(),w;
		//取出队头
		b[u]=1;//标记
		q.pop();//弹出
		将所有可能判断后加入队列;
	}
   输出;
}

到这道题的应用:

先说一些简单的(ti):
把它A了再说

P1588 [USACO07OPEN]Catch That Cow S

P1135 奇怪的电梯

以下来到正题:
这道题目看似是最短路算法,其实因为无权值所以可以用bfs!!(用spfa由于没有很好的利用这一点,所以比较慢据说还有被卡的可能!!

然后很容易想到:

int m,x,y;
cin>>n>>m;
for(int i=1;i<=m;++i){
	cin>>x>>y;
	add(x,y);
	add(y,x);
}
for(int i=1;i<=n;++i){
	s[i]=2147483647;//至于为什么要定义成这样
    ~~自己想!~~
} 
bfs(1);
return 0;

可是bfs怎么写呢?

经过十几分钟的努力,本蒟蒻想到了如下办法:

用b数组标记访问,s数组标记步数,sl数组标记最短路的数量!

两种可能:

  1. 之前未访问:
    标记访问,步数+1,数量直接移。

  2. 之前已访问:
    数量相加!!

核心代码:

for(int i=head[us];i;i=e[i].next){
	int u=e[i].u,v=e[i].v;//获取u、v
	if(b[v]==0){   //没走过
		q.push(v);  //进入队列
		b[v]=1;  //标记
		s[v]=s[u]+1; //步数+1
		sl[v]=sl[u];//因为是之前没有访问的,所以数量直接移过来
		sl[v]%=100003; 
	}
	else if(b[v]==1&&s[v]==s[u]+1){  //新的路径 
		sl[v]+=sl[u];  //发现居然还有一种新的最短路!数量加起来
		sl[v]%=100003;
	}
}

之后就是一些初始化的问题了:

b[x]=1;sl[x]=1;s[x]=0;

code:(全部代码)

#include<bits/stdc++.h>
using namespace std;
struct node{
	int u,v,next;
}e[40000001];
int head[1000001],b[1000001],s[1000001],sl[1000001],tot,n;
void add(int x,int y){
	e[++tot].u=x;
	e[tot].v=y;
	e[tot].next=head[x];
	head[x]=tot;
}
void bfs(int x){
	queue<int>q;
	q.push(x);
	b[x]=1;sl[x]=1;s[x]=0;
	while(!q.empty()){
		int us=q.front();
		b[us]=1;
		//cout<<"us:"<<us<<endl;
		q.pop();
		//cout<<"i:";
		//int u=e[i].u,v=e[i].v;
		for(int i=head[us];i;i=e[i].next){
			int u=e[i].u,v=e[i].v;
			//cout<<u<<" ";
			if(b[v]==0){
				q.push(v);
				b[v]=1;
				s[v]=s[u]+1;
				sl[v]=sl[u];
				sl[v]%=100003; 
			}
			else if(b[v]==1&&s[v]==s[u]+1){  //新的路径 
				//q.push(e[i].v);
				//s[e[i].v]=s[e[i].u]+1;
				sl[v]+=sl[u];
				sl[v]%=100003;
			}
		}
		//cout<<endl;
	}
	for(int i=1;i<=n;++i){
		//if(i==1){
		//	cout<<"1"<<endl; 
		//}
		if(s[i]==2147483647){
			cout<<"0"<<endl;
		}
		else{
			cout<<sl[i]<<endl;
		}
	}
}
int main(){
	int m,x,y;
	cin>>n>>m;
	for(int i=1;i<=m;++i){
		cin>>x>>y;
		add(x,y);
		add(y,x);
	}
	for(int i=1;i<=n;++i){
		s[i]=2147483647;
	} 
	bfs(1);
	return 0;
}

byebye~~

看着我这么认真,点个赞撒

posted @ 2020-04-06 17:43  Cosmos_craker  阅读(161)  评论(0编辑  收藏  举报