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
以下来到正题:
这道题目看似是最短路算法,其实因为无权值所以可以用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,数量直接移。 -
之前已访问:
数量相加!!
核心代码:
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~~
看着我这么认真,点个赞撒