zoukankan      html  css  js  c++  java
  • 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~~

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

  • 相关阅读:
    OSCP Learning Notes Buffer Overflows(3)
    OSCP Learning Notes Buffer Overflows(5)
    OSCP Learning Notes Exploit(3)
    OSCP Learning Notes Exploit(4)
    OSCP Learning Notes Exploit(1)
    OSCP Learning Notes Netcat
    OSCP Learning Notes Buffer Overflows(4)
    OSCP Learning Notes Buffer Overflows(1)
    OSCP Learning Notes Exploit(2)
    C++格式化输出 Learner
  • 原文地址:https://www.cnblogs.com/Craker/p/12643161.html
Copyright © 2011-2022 走看看