0
点赞
收藏
分享

微信扫一扫

1003 Emergency (25 point(s))


 1003 Emergency (25 point(s))

SPFA 部分未通过  19分

思路:

1.SPFA可以在有路径长度为负的情况下,也能够实现最短路径

2.需要一个距离数组  d  对应的表示该源到图中所有点的最短距离 初始设为INF

3.需要一个是否在队列的判定数组

4.需要一个每个节点入队次数的数组,因为可能有负环,所以要做好控制,另外,因为最短路径其实是可以生成最短路径树的,最短路径树的长度最大不超过定点个树V,并且在起始的时候d[start] =0 ,就是从开始点的起始位置,实际上,距离就是0,所以已经定好了,基于这样的理论,所以每个节点实际上入队不会超过v次,也即整个最短路径树的更新次数.

5.若对应的点的距离改变了,那么相应的后续与相连的数据必定也要在最短路径上发生变更,这就是实现思想.

#include<vector>
#include<iostream>
#include<queue>
#include<set>
using namespace std;

struct node{
    int v;
    int l;
    node(int v,int l):v(v),l(l){}
};

int main(){
    int const INF = 0x3f3f3f3f;
    int const MAXN = 510;

    //map
    vector<node>map[MAXN];
    //if in queue;
    bool in_que[MAXN];
    fill(in_que,in_que+MAXN,false);

    //in queue number
    int in_count[MAXN];
    fill(in_count,in_count+MAXN,0);

    //wegiht count;
    int w[MAXN];
    fill(w,w+MAXN,0);

    //wegiht ;
    int weight[MAXN];

    //distence;
    int d[MAXN];
    fill(d,d+MAXN,INF);

    int num[MAXN];
    fill(num,num+MAXN,0);


    queue<int> que_map;

    set<int> pre[MAXN];

    int N,M,C1,C2;

    cin>>N>>M>>C1>>C2;

    for(int i=0;i<N;i++){
        cin>>weight[i];
    }

    for(int i=0;i<M;i++){
        int c1,c2,lenth;
        cin>>c1>>c2>>lenth;
        map[c1].push_back(node(c2,lenth));
        map[c2].push_back(node(c1,lenth));

    }

//    for(int i=0;i<N;i++){

//        int length = map[i].size();
//        for(int j=0;j<length;j++){
//            cout<<i<<" "<<map[i][j].v<<" "<<map[i][j].l<<endl;
//        }
//    }

    d[C1] = 0;
    que_map.push(C1);
    w[C1] = weight[C1];
    in_que[C1] = true;
    in_count[C1] = 1;
    num[C1] = 1;

    while(!que_map.empty()){

        int u = que_map.front();

        que_map.pop();
        in_que[u] = false;

        if(in_count[u]>=N){
            break;
        }

        int lenth = map[u].size();

        for(int i=0;i<lenth;i++){
            int v = map[u][i].v;
            int l = map[u][i].l;

            if(d[u]+l<d[v]){
                d[v] = d[u]+l;
                w[v] = w[u]+weight[v];
                num[v]=num[u];
                pre[v].clear();
                pre[v].insert(u);
                if(!in_que[v]){
                    que_map.push(v);
                    in_que[v] = true;
                    in_count[v]++;
                }
            }else if(d[u]+l==d[v]){
                pre[v].insert(u);
                num[v] = 0;
                set<int>::iterator it = pre[v].begin();
                for(;it!=pre[v].end();it++){
                    num[v]+=num[*it];
                }
                if(w[u]+weight[v]>w[v]){
                     w[v] = w[u]+weight[v];
                }
            }
        }
    }
    cout<<num[C2]<<" "<<w[C2]<<endl;

    return 0;
}

spfa +dfs 满分实现 

#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
#include<set>

using namespace std;

const int MAXN = 10000; 
int N,M;
const int INF = 0xf3f3f3f;
int weight[MAXN];
struct node{
	int to,len,rec;
	node(){}
	node(int to,int len,int rec):to(to),len(len),rec(rec){};
};

int innum[MAXN];
bool inque[MAXN];
int dist[MAXN];

set<int> pre[MAXN];
vector<node> map_[MAXN];
void add_edge(int a, int b, int cost){
	map_[a].push_back(node(b,cost,map_[b].size()));	
	map_[b].push_back(node(a,cost,map_[a].size()-1));	
}


vector<int> temp_path;
int cal(vector<int> path){
	int ans = 0;
	for(int i = path.size()-1; i>=0;i--){
		ans += weight[path[i]];
	}
	return ans;
}
int max_ = -1;
int  pathNum = 0;
void dfs_out(int start,int end){
	if(start == end){
		temp_path.push_back(start);
		int ans = cal(temp_path);
		pathNum++;
		if(ans > max_){
			max_ = ans;
		}
		temp_path.pop_back();
		return;
	}
	temp_path.push_back(end);
	
	set<int>::iterator it = pre[end].begin();
	for(;it!=pre[end].end();it++){
//		printf("%d\n",*it);
		dfs_out(start,*it);
	}
	temp_path.pop_back();
}

bool spfa(int start){
	fill(dist,dist+N,INF);
	memset(inque,0,sizeof(inque)); 
	memset(innum,0,sizeof(innum)); 
	dist[start] = 0;
	inque[start] = 1;
	innum[start] = 1;
	queue<node> que;
	que.push(node(start,0,0));	
	while(!que.empty()){
		node temp = que.front(); que.pop();
		inque[temp.to] = false;
		for(int i=0;i<map_[temp.to].size();i++){
			node nnode = map_[temp.to][i];
			if(dist[nnode.to]> dist[temp.to] + nnode.len){
				dist[nnode.to] = dist[temp.to] + nnode.len;
				pre[nnode.to].clear();
				pre[nnode.to].insert(temp.to);
				
				if(inque[nnode.to]) continue;
				inque[nnode.to] = 1;
				que.push(nnode);
				if(innum[nnode.to]>= N-1) return false;
				innum[nnode.to]++;
			}else if(dist[nnode.to]== dist[temp.to] + nnode.len){
				pre[nnode.to].insert(temp.to);
			}

		}
	}
	return true;
}


int main(){
	int start,end;
	scanf("%d%d%d%d",&N,&M,&start,&end);
	for(int i=0;i<N;i++)
		scanf("%d",&weight[i]);
	for(int i=0;i<M;i++){
		int a,b,cost;
		scanf("%d%d%d",&a,&b,&cost);
		add_edge(a,b,cost);
	}
	
	spfa(start);
	
	dfs_out(start,end);
	
	printf("%d %d\n",pathNum,max_);

	return 0;
}

 

举报

相关推荐

0 条评论